{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "toc_visible": true,
      "machine_shape": "hm",
      "gpuType": "V100",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU",
    "gpuClass": "standard"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/mrdbourke/tensorflow-deep-learning/blob/main/01_neural_network_regression_in_tensorflow.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UPgo18-N1gSi"
      },
      "source": [
        "# 01. Neural Network Regression with TensorFlow\n",
        "\n",
        "There are many definitions for a [regression problem](https://en.wikipedia.org/wiki/Regression_analysis) but in our case, we're going to simplify it to be: predicting a number.\n",
        "\n",
        "For example, you might want to:\n",
        "- Predict the selling price of houses given information about them (such as number of rooms, size, number of bathrooms).\n",
        "- Predict the coordinates of a bounding box of an item in an image.\n",
        "- Predict the cost of medical insurance for an individual given their demographics (age, sex, gender, race).\n",
        "\n",
        "In this notebook, we're going to set the foundations for how you can take a sample of inputs (this is your data), build a neural network to discover patterns in those inputs and then make a prediction (in the form of a number) based on those inputs.\n",
        "\n",
        "## What we're going to cover\n",
        "\n",
        "Specifically, we're going to go through doing the following with TensorFlow:\n",
        "- Architecture of a regression model\n",
        "- Input shapes and output shapes\n",
        "  - `X`: features/data (inputs)\n",
        "  - `y`: labels (outputs)\n",
        "- Creating custom data to view and fit\n",
        "- Steps in modelling\n",
        "  - Creating a model\n",
        "  - Compiling a model\n",
        "    - Defining a loss function\n",
        "    - Setting up an optimizer\n",
        "    - Creating evaluation metrics\n",
        "  - Fitting a model (getting it to find patterns in our data)\n",
        "- Evaluating a model\n",
        "  - Visualizng the model (\"visualize, visualize, visualize\")\n",
        "  - Looking at training curves\n",
        "  - Compare predictions to ground truth (using our evaluation metrics)\n",
        "- Saving a model (so we can use it later)\n",
        "- Loading a model\n",
        "\n",
        "Don't worry if none of these make sense now, we're going to go through each.\n",
        "\n",
        "## How you can use this notebook\n",
        "\n",
        "You can read through the descriptions and the code (it should all run), but there's a better option.\n",
        "\n",
        "Write all of the code yourself.\n",
        "\n",
        "Yes. I'm serious. Create a new notebook, and rewrite each line by yourself. Investigate it, see if you can break it, why does it break?\n",
        "\n",
        "You don't have to write the text descriptions but writing the code yourself is a great way to get hands-on experience.\n",
        "\n",
        "Don't worry if you make mistakes, we all do. The way to get better and make less mistakes is to **write more code**."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "etAu7oCZ8r_G"
      },
      "source": [
        "## Typical architecture of a regresison neural network\n",
        "\n",
        "The word *typical* is on purpose.\n",
        "\n",
        "Why?\n",
        "\n",
        "Because there are many different ways (actually, there's almost an infinite number of ways) to write neural networks.\n",
        "\n",
        "But the following is a generic setup for ingesting a collection of numbers, finding patterns in them and then outputting some kind of target number.\n",
        "\n",
        "Yes, the previous sentence is vague but we'll see this in action shortly.\n",
        "\n",
        "| **Hyperparameter** | **Typical value** |\n",
        "| --- | --- |\n",
        "| Input layer shape | Same shape as number of features (e.g. 3 for # bedrooms, # bathrooms, # car spaces in housing price prediction) |\n",
        "| Hidden layer(s) | Problem specific, minimum = 1, maximum = unlimited |\n",
        "| Neurons per hidden layer | Problem specific, generally 10 to 100 |\n",
        "| Output layer shape | Same shape as desired prediction shape (e.g. 1 for house price) |\n",
        "| Hidden activation | Usually [ReLU](https://www.kaggle.com/dansbecker/rectified-linear-units-relu-in-deep-learning) (rectified linear unit) |\n",
        "| Output activation | None, ReLU, logistic/tanh |\n",
        "| Loss function | [MSE](https://en.wikipedia.org/wiki/Mean_squared_error) (mean square error) or [MAE](https://en.wikipedia.org/wiki/Mean_absolute_error) (mean absolute error)/Huber (combination of MAE/MSE) if outliers |\n",
        "| Optimizer | [SGD](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/SGD) (stochastic gradient descent), [Adam](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam) |\n",
        "\n",
        "*Table 1: Typical architecture of a regression network. Source: Adapted from page 293 of [Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow Book by Aurélien Géron](https://www.oreilly.com/library/view/hands-on-machine-learning/9781492032632/)*\n",
        "\n",
        "Again, if you're new to neural networks and deep learning in general, much of the above table won't make sense. But don't worry, we'll be getting hands-on with all of it soon.\n",
        "\n",
        "> 🔑 **Note:** A **hyperparameter** in machine learning is something a data analyst or developer can set themselves, where as a **parameter** usually describes something a model learns on its own (a value not explicitly set by an analyst).\n",
        "\n",
        "Okay, enough talk, let's get started writing code.\n",
        "\n",
        "To use TensorFlow, we'll import it as the common alias `tf` (short for TensorFlow)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FMqsqKpk7TrH",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "71dcbb23-77b4-4032-9392-d8f93ee8262a"
      },
      "source": [
        "import tensorflow as tf\n",
        "print(tf.__version__) # check the version (should be 2.x+)\n",
        "\n",
        "import datetime\n",
        "print(f\"Notebook last run (end-to-end): {datetime.datetime.now()}\")"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "2.12.0\n",
            "Notebook last run (end-to-end): 2023-05-07 23:10:01.302908\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8clMYxrF6Mzv"
      },
      "source": [
        "## Creating data to view and fit\n",
        "\n",
        "Since we're working on a **regression problem** (predicting a number) let's create some linear data (a straight line) to model."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "G43tWFof6i7T",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 435
        },
        "outputId": "6ccaf308-ea75-4fc6-c049-60587705204e"
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Create features\n",
        "X = np.array([-7.0, -4.0, -1.0, 2.0, 5.0, 8.0, 11.0, 14.0])\n",
        "\n",
        "# Create labels\n",
        "y = np.array([3.0, 6.0, 9.0, 12.0, 15.0, 18.0, 21.0, 24.0])\n",
        "\n",
        "# Visualize it\n",
        "plt.scatter(X, y);"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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TR9eq+njox/96HWHSYQvxAIAiREnAEBSxEmi6urqoqurK+rq6io9ClfgtZpevF7Th9dq+ij3a5XcF2IBgJnNJycAQFLECQCQFHECACRFnAAASREn08DHPvaxyOVyY27f/va3Kz0Wv/DCCy/Exz72saivr48VK1bE/v37Kz0SF3n66afHvYduu+22So/FL+zevTs6Ozujubk5crlcbNu2bcz+LMvim9/8ZhSLxbjpppti1apV8dZbb1Vm2BnuSq/V+vXrx73XOjo6Jv084mSa+PM///Po7+8fvT366KOVHomI+Md//MfYtGlTdHV1xYEDB+L222+P1atXx/Hjxys9Ghf59Kc/PeY99Prrr1d6JH7h7Nmzcfvtt8cLL7ww4f5nn302vvOd78SLL74Y+/bti4985COxevXqGBoamuJJudJrFRHR0dEx5r326quvTvp5klu+nok1NDREoVCo9Bhc5LnnnouHH344fu/3fi8iIl588cX413/91/j7v//7+MY3vlHh6bjQrFmzvIcStWbNmlizZs2E+7Isi+effz6efPLJuO+++yIi4uWXX4758+fHtm3b4v7775/KUWe8y71W59XV1V33e80nJ9PEt7/97Zg7d2786q/+avzVX/1V/PznP6/0SDPez372s3jjjTdi1apVo9tqampi1apVsWfPngpOxkTeeuutaG5ujkWLFsVXvvKVeOeddyo9Elehr68vBgYGxrzP8vl8rFixwvssUTt37oympqZYsmRJbNiwIU6cODHpx/DJyTTwR3/0R7F8+fJobGyMH//4x/HEE09Ef39/PPfcc5UebUb73//93xgeHo758+eP2T5//vz46U9/WqGpmMiKFSvipZdeiiVLlkR/f390d3fH5z//+ejt7Y2GhoZKj8dlDAwMRERM+D47v490dHR0xBe/+MVobW2NI0eOxJ/92Z/FmjVrYs+ePVFbW3vVjyNOKuQb3/hGPPPMM5c95r//+7/jtttui02bNo1uW7ZsWcyePTv+4A/+IDZv3mxZZ7gKF34MvWzZslixYkUsXLgw/umf/ikeeuihCk4G1eXC02yf+cxnYtmyZbF48eLYuXNn3H333Vf9OOKkQr761a/G+vXrL3vMokWLJty+YsWK+PnPfx5vv/12LFmy5AZMx9W45ZZbora2No4dOzZm+7Fjx3y3IXE333xzfPKTn4zDhw9XehSu4Px76dixY1EsFke3Hzt2LH7lV36lQlNxtRYtWhS33HJLHD58WJxMB/PmzYt58+Zd088ePHgwampqoqmpqcxTMRmzZ8+Oz372s7Fjx45Yu3ZtRESMjIzEjh074pFHHqnscFzWmTNn4siRI/G7v/u7lR6FK2htbY1CoRA7duwYjZHBwcHYt29fbNiwobLDcUXvvvtunDhxYkxYXg1xkrg9e/bEvn374q677oqGhobYs2dPPP7447Fu3br45V/+5UqPN+Nt2rQpHnzwwfi1X/u1aG9vj+effz7Onj07evUOafja174WnZ2dsXDhwnjvvfeiq6sramtr44EHHqj0aMQHsXjhp1h9fX1x8ODBaGxsjAULFsRjjz0W3/rWt+ITn/hEtLa2xlNPPRXNzc2j/yhg6lzutWpsbIzu7u740pe+FIVCIY4cORJf//rX4+Mf/3isXr16ck+UkbQ33ngjW7FiRZbP57P6+vrsU5/6VPaXf/mX2dDQUKVH4xf++q//OluwYEE2e/bsrL29Pdu7d2+lR+IiX/7yl7NisZjNnj07++hHP5p9+ctfzg4fPlzpsfiF//iP/8giYtztwQcfzLIsy0ZGRrKnnnoqmz9/flZXV5fdfffd2ZtvvlnZoWeoy71W//d//5fde++92bx587IPfehD2cKFC7OHH344GxgYmPTz5LIsy8qSUwAAZWCdEwAgKeIEAEiKOAEAkiJOAICkiBMAICniBABIijgBAJIiTgCApIgTACAp4gQASIo4AQCSIk4AgKT8P0zcr4hLXzkpAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9ONZF8un7_xy"
      },
      "source": [
        "Before we do any modelling, can you calculate the pattern between `X` and `y`?\n",
        "\n",
        "For example, say I asked you, based on this data what the `y` value would be if `X` was 17.0?\n",
        "\n",
        "Or how about if `X` was -10.0?\n",
        "\n",
        "This kind of pattern discovery is the essence of what we'll be building neural networks to do for us."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zNCXxHnF6jjZ"
      },
      "source": [
        "## Regression input shapes and output shapes\n",
        "\n",
        "One of the most important concepts when working with neural networks are the input and output shapes.\n",
        "\n",
        "The **input shape** is the shape of your data that goes into the model.\n",
        "\n",
        "The **output shape** is the shape of your data you want to come out of your model.\n",
        "\n",
        "These will differ depending on the problem you're working on.\n",
        "\n",
        "Neural networks accept numbers and output numbers. These numbers are typically represented as tensors (or arrays).\n",
        "\n",
        "Before, we created data using NumPy arrays, but we could do the same with tensors."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XrXQ3m0prWXa",
        "outputId": "023e18d3-1c67-4802-c52b-006649b7321f"
      },
      "source": [
        "# Example input and output shapes of a regression model\n",
        "house_info = tf.constant([\"bedroom\", \"bathroom\", \"garage\"])\n",
        "house_price = tf.constant([939700])\n",
        "house_info, house_price"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(<tf.Tensor: shape=(3,), dtype=string, numpy=array([b'bedroom', b'bathroom', b'garage'], dtype=object)>,\n",
              " <tf.Tensor: shape=(1,), dtype=int32, numpy=array([939700], dtype=int32)>)"
            ]
          },
          "metadata": {},
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Yi3VWKH6sRrZ",
        "outputId": "cc06303a-00fd-4eb1-b7a7-c4dd8c5c670f"
      },
      "source": [
        "house_info.shape"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "TensorShape([3])"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kOxyr9sR6m9X",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 435
        },
        "outputId": "8615828f-8811-4bdd-f69d-bca7575977fe"
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# Create features (using tensors)\n",
        "X = tf.constant([-7.0, -4.0, -1.0, 2.0, 5.0, 8.0, 11.0, 14.0])\n",
        "\n",
        "# Create labels (using tensors)\n",
        "y = tf.constant([3.0, 6.0, 9.0, 12.0, 15.0, 18.0, 21.0, 24.0])\n",
        "\n",
        "# Visualize it\n",
        "plt.scatter(X, y);"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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TR9eq+njox/96HWHSYQvxAIAiREnAEBSxEmi6urqoqurK+rq6io9ClfgtZpevF7Th9dq+ij3a5XcF2IBgJnNJycAQFLECQCQFHECACRFnAAASREn08DHPvaxyOVyY27f/va3Kz0Wv/DCCy/Exz72saivr48VK1bE/v37Kz0SF3n66afHvYduu+22So/FL+zevTs6Ozujubk5crlcbNu2bcz+LMvim9/8ZhSLxbjpppti1apV8dZbb1Vm2BnuSq/V+vXrx73XOjo6Jv084mSa+PM///Po7+8fvT366KOVHomI+Md//MfYtGlTdHV1xYEDB+L222+P1atXx/Hjxys9Ghf59Kc/PeY99Prrr1d6JH7h7Nmzcfvtt8cLL7ww4f5nn302vvOd78SLL74Y+/bti4985COxevXqGBoamuJJudJrFRHR0dEx5r326quvTvp5klu+nok1NDREoVCo9Bhc5LnnnouHH344fu/3fi8iIl588cX413/91/j7v//7+MY3vlHh6bjQrFmzvIcStWbNmlizZs2E+7Isi+effz6efPLJuO+++yIi4uWXX4758+fHtm3b4v7775/KUWe8y71W59XV1V33e80nJ9PEt7/97Zg7d2786q/+avzVX/1V/PznP6/0SDPez372s3jjjTdi1apVo9tqampi1apVsWfPngpOxkTeeuutaG5ujkWLFsVXvvKVeOeddyo9Elehr68vBgYGxrzP8vl8rFixwvssUTt37oympqZYsmRJbNiwIU6cODHpx/DJyTTwR3/0R7F8+fJobGyMH//4x/HEE09Ef39/PPfcc5UebUb73//93xgeHo758+eP2T5//vz46U9/WqGpmMiKFSvipZdeiiVLlkR/f390d3fH5z//+ejt7Y2GhoZKj8dlDAwMRERM+D47v490dHR0xBe/+MVobW2NI0eOxJ/92Z/FmjVrYs+ePVFbW3vVjyNOKuQb3/hGPPPMM5c95r//+7/jtttui02bNo1uW7ZsWcyePTv+4A/+IDZv3mxZZ7gKF34MvWzZslixYkUsXLgw/umf/ikeeuihCk4G1eXC02yf+cxnYtmyZbF48eLYuXNn3H333Vf9OOKkQr761a/G+vXrL3vMokWLJty+YsWK+PnPfx5vv/12LFmy5AZMx9W45ZZbora2No4dOzZm+7Fjx3y3IXE333xzfPKTn4zDhw9XehSu4Px76dixY1EsFke3Hzt2LH7lV36lQlNxtRYtWhS33HJLHD58WJxMB/PmzYt58+Zd088ePHgwampqoqmpqcxTMRmzZ8+Oz372s7Fjx45Yu3ZtRESMjIzEjh074pFHHqnscFzWmTNn4siRI/G7v/u7lR6FK2htbY1CoRA7duwYjZHBwcHYt29fbNiwobLDcUXvvvtunDhxYkxYXg1xkrg9e/bEvn374q677oqGhobYs2dPPP7447Fu3br45V/+5UqPN+Nt2rQpHnzwwfi1X/u1aG9vj+effz7Onj07evUOafja174WnZ2dsXDhwnjvvfeiq6sramtr44EHHqj0aMQHsXjhp1h9fX1x8ODBaGxsjAULFsRjjz0W3/rWt+ITn/hEtLa2xlNPPRXNzc2j/yhg6lzutWpsbIzu7u740pe+FIVCIY4cORJf//rX4+Mf/3isXr16ck+UkbQ33ngjW7FiRZbP57P6+vrsU5/6VPaXf/mX2dDQUKVH4xf++q//OluwYEE2e/bsrL29Pdu7d2+lR+IiX/7yl7NisZjNnj07++hHP5p9+ctfzg4fPlzpsfiF//iP/8giYtztwQcfzLIsy0ZGRrKnnnoqmz9/flZXV5fdfffd2ZtvvlnZoWeoy71W//d//5fde++92bx587IPfehD2cKFC7OHH344GxgYmPTz5LIsy8qSUwAAZWCdEwAgKeIEAEiKOAEAkiJOAICkiBMAICniBABIijgBAJIiTgCApIgTACAp4gQASIo4AQCSIk4AgKT8P0zcr4hLXzkpAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zaPxco6E9i1_"
      },
      "source": [
        "Our goal here will be to use `X` to predict `y`.\n",
        "\n",
        "So our **input** will be `X` and our **output** will be `y`.\n",
        "\n",
        "Knowing this, what do you think our input and output shapes will be?\n",
        "\n",
        "Let's take a look."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "j1oT1gmB9iX-",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d7f1666a-7fcd-4dd0-d7a2-37219c892dce"
      },
      "source": [
        "# Take a single example of X\n",
        "input_shape = X[0].shape \n",
        "\n",
        "# Take a single example of y\n",
        "output_shape = y[0].shape\n",
        "\n",
        "input_shape, output_shape # these are both scalars (no shape)"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(TensorShape([]), TensorShape([]))"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "m4txxFTL_EEX"
      },
      "source": [
        "Huh?\n",
        "\n",
        "From this it seems our inputs and outputs have no shape?\n",
        "\n",
        "How could that be?\n",
        "\n",
        "It's because no matter what kind of data we pass to our model, it's always going to take as input and return as output some kind of tensor.\n",
        "\n",
        "But in our case because of our dataset (only 2 small lists of numbers), we're looking at a special kind of tensor, more specifically a rank 0 tensor or a scalar."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Dag5y4MPaTmc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "02fad51d-1fb9-4a09-e62d-52cdd99bd030"
      },
      "source": [
        "# Let's take a look at the single examples invidually\n",
        "X[0], y[0]"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(<tf.Tensor: shape=(), dtype=float32, numpy=-7.0>,\n",
              " <tf.Tensor: shape=(), dtype=float32, numpy=3.0>)"
            ]
          },
          "metadata": {},
          "execution_count": 7
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fKtihU57_cOY"
      },
      "source": [
        "In our case, we're trying to build a model to predict the pattern between `X[0]` equalling `-7.0` and `y[0]` equalling `3.0`.\n",
        "\n",
        "So now we get our answer, we're trying to use 1 `X` value to predict 1 `y` value.\n",
        "\n",
        "You might be thinking, \"this seems pretty complicated for just predicting a straight line...\".\n",
        "\n",
        "And you'd be right.\n",
        "\n",
        "But the concepts we're covering here, the concepts of input and output shapes to a model are fundamental. \n",
        "\n",
        "In fact, they're probably two of the things you'll spend the most time on when you work with neural networks: **making sure your input and outputs are in the correct shape**.\n",
        "\n",
        "If it doesn't make sense now, we'll see plenty more examples later on (soon you'll notice the input and output shapes can be almost anything you can imagine).\n",
        "\n",
        "![example of input and output shapes for a housing price prediction problem](https://raw.githubusercontent.com/mrdbourke/tensorflow-deep-learning/main/images/01-input-and-output-shapes-housing-prices.png)\n",
        "*If you were working on building a machine learning algorithm for predicting housing prices, your inputs may be number of bedrooms, number of bathrooms and number of garages, giving you an input shape of 3 (3 different features). And since you're trying to predict the price of the house, your output shape would be 1.*"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PhAIqjrn6olF"
      },
      "source": [
        "## Steps in modelling with TensorFlow\n",
        "\n",
        "Now we know what data we have as well as the input and output shapes, let's see how we'd build a neural network to model it.\n",
        "\n",
        "In TensorFlow, there are typically 3 fundamental steps to creating and training a model.\n",
        "\n",
        "1. **Creating a model** - piece together the layers of a neural network yourself (using the [Functional](https://www.tensorflow.org/guide/keras/functional) or [Sequential API](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential)) or import a previously built model (known as transfer learning).\n",
        "2. **Compiling a model** - defining how a models performance should be measured (loss/metrics) as well as defining how it should improve (optimizer). \n",
        "3. **Fitting a model** - letting the model try to find patterns in the data (how does `X` get to `y`). \n",
        "\n",
        "Let's see these in action using the [Keras Sequential API](https://www.tensorflow.org/api_docs/python/tf/keras/Sequential) to build a model for our regression data. And then we'll step through each.\n",
        "\n",
        "> **Note:** If you're using [TensorFlow 2.7.0](https://github.com/tensorflow/tensorflow/releases/tag/v2.7.0)+, the `fit()` function no longer upscales input data to go from `(batch_size, )` to `(batch_size, 1)`. To fix this, you'll need to expand the dimension of input data using `tf.expand_dims(input_data, axis=-1)`.\n",
        ">\n",
        "> In our case, this means instead of using `model.fit(X, y, epochs=5)`, use `model.fit(tf.expand_dims(X, axis=-1), y, epochs=5)`. "
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "P9jj-OE16yCn",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "014780da-d5c0-4909-cb11-ea269eb07229"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Create a model using the Sequential API\n",
        "model = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "model.compile(loss=tf.keras.losses.mae, # mae is short for mean absolute error\n",
        "              optimizer=tf.keras.optimizers.SGD(), # SGD is short for stochastic gradient descent\n",
        "              metrics=[\"mae\"])\n",
        "\n",
        "# Fit the model\n",
        "# model.fit(X, y, epochs=5) # this will break with TensorFlow 2.7.0+\n",
        "model.fit(tf.expand_dims(X, axis=-1), y, epochs=5)"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/5\n",
            "1/1 [==============================] - 6s 6s/step - loss: 19.2976 - mae: 19.2976\n",
            "Epoch 2/5\n",
            "1/1 [==============================] - 0s 18ms/step - loss: 19.0164 - mae: 19.0164\n",
            "Epoch 3/5\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 18.7351 - mae: 18.7351\n",
            "Epoch 4/5\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 18.4539 - mae: 18.4539\n",
            "Epoch 5/5\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 18.1726 - mae: 18.1726\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f00663d2680>"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bbjCwkEtetB9"
      },
      "source": [
        "Boom!\n",
        "\n",
        "We've just trained a model to figure out the patterns between `X` and `y`.\n",
        "\n",
        "How do you think it went?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VWLpG2U3erWo",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b7c8763e-b90a-4598-cd09-6a88019b4e17"
      },
      "source": [
        "# Check out X and y\n",
        "X, y"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(<tf.Tensor: shape=(8,), dtype=float32, numpy=array([-7., -4., -1.,  2.,  5.,  8., 11., 14.], dtype=float32)>,\n",
              " <tf.Tensor: shape=(8,), dtype=float32, numpy=array([ 3.,  6.,  9., 12., 15., 18., 21., 24.], dtype=float32)>)"
            ]
          },
          "metadata": {},
          "execution_count": 9
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0ZpkaI_Oe6no"
      },
      "source": [
        "What do you think the outcome should be if we passed our model an `X` value of 17.0?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "X86cD66Qeo-8",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "4a8e530b-47e6-414d-90e1-e726cb7b426a"
      },
      "source": [
        "# Make a prediction with the model\n",
        "model.predict([17.0])"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 115ms/step\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[-16.701845]], dtype=float32)"
            ]
          },
          "metadata": {},
          "execution_count": 10
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2YoKIqhffq33"
      },
      "source": [
        "It doesn't go very well... it should've output something close to 27.0.\n",
        "\n",
        "> 🤔 **Question:** What's Keras? I thought we were working with TensorFlow but every time we write TensorFlow code, `keras` comes after `tf` (e.g. `tf.keras.layers.Dense()`)?\n",
        "\n",
        "Before TensorFlow 2.0+, [Keras](https://keras.io/) was an API designed to be able to build deep learning models with ease. Since TensorFlow 2.0+, its functionality has been tightly integrated within the TensorFlow library."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qAPk1T3xgOm4"
      },
      "source": [
        "## Improving a model\n",
        "\n",
        "How do you think you'd improve upon our current model?\n",
        "\n",
        "If you guessed by tweaking some of the things we did above, you'd be correct.\n",
        "\n",
        "To improve our model, we alter almost every part of the 3 steps we went through before.\n",
        "\n",
        "1. **Creating a model** - here you might want to add more layers, increase the number of hidden units (also called neurons) within each layer, change the activation functions of each layer.\n",
        "2. **Compiling a model** - you might want to choose optimization function or perhaps change the **learning rate** of the optimization function.\n",
        "3. **Fitting a model** - perhaps you could fit a model for more **epochs** (leave it training for longer) or on more data (give the model more examples to learn from).\n",
        "\n",
        "![various options you can use to improve a neural network model](https://raw.githubusercontent.com/mrdbourke/tensorflow-deep-learning/main/images/02-improving-a-model-from-model-perspective.png)\n",
        "*There are many different ways to potentially improve a neural network. Some of the most common include: increasing the number of layers (making the network deeper), increasing the number of hidden units (making the network wider) and changing the learning rate. Because these values are all human-changeable, they're referred to as [hyperparameters](https://en.wikipedia.org/wiki/Hyperparameter_(machine_learning)) and the practice of trying to find the best hyperparameters is referred to as [hyperparameter tuning](https://en.wikipedia.org/wiki/Hyperparameter_optimization).*\n",
        "\n",
        "Woah. We just introduced a bunch of possible steps. The important thing to remember is how you alter each of these will depend on the problem you're working on.\n",
        "\n",
        "And the good thing is, over the next few problems, we'll get hands-on with all of them.\n",
        "\n",
        "For now, let's keep it simple, all we'll do is train our model for longer (everything else will stay the same)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MI0LammMgWcN",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "edd6fa7a-6ea0-4227-e9e8-48bf4d809fa8"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Create a model (same as above)\n",
        "model = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile model (same as above)\n",
        "model.compile(loss=tf.keras.losses.mae,\n",
        "              optimizer=tf.keras.optimizers.SGD(),\n",
        "              metrics=[\"mae\"])\n",
        "\n",
        "# Fit model (this time we'll train for longer)\n",
        "model.fit(tf.expand_dims(X, axis=-1), y, epochs=100) # train for 100 epochs not 10"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/100\n",
            "1/1 [==============================] - 1s 604ms/step - loss: 12.9936 - mae: 12.9936\n",
            "Epoch 2/100\n",
            "1/1 [==============================] - 0s 14ms/step - loss: 12.8611 - mae: 12.8611\n",
            "Epoch 3/100\n",
            "1/1 [==============================] - 0s 16ms/step - loss: 12.7286 - mae: 12.7286\n",
            "Epoch 4/100\n",
            "1/1 [==============================] - 0s 16ms/step - loss: 12.5961 - mae: 12.5961\n",
            "Epoch 5/100\n",
            "1/1 [==============================] - 0s 15ms/step - loss: 12.4636 - mae: 12.4636\n",
            "Epoch 6/100\n",
            "1/1 [==============================] - 0s 15ms/step - loss: 12.3311 - mae: 12.3311\n",
            "Epoch 7/100\n",
            "1/1 [==============================] - 0s 15ms/step - loss: 12.1986 - mae: 12.1986\n",
            "Epoch 8/100\n",
            "1/1 [==============================] - 0s 16ms/step - loss: 12.0661 - mae: 12.0661\n",
            "Epoch 9/100\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 11.9336 - mae: 11.9336\n",
            "Epoch 10/100\n",
            "1/1 [==============================] - 0s 14ms/step - loss: 11.8011 - mae: 11.8011\n",
            "Epoch 11/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 11.6686 - mae: 11.6686\n",
            "Epoch 12/100\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 11.5361 - mae: 11.5361\n",
            "Epoch 13/100\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 11.4036 - mae: 11.4036\n",
            "Epoch 14/100\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 11.2711 - mae: 11.2711\n",
            "Epoch 15/100\n",
            "1/1 [==============================] - 0s 13ms/step - loss: 11.1386 - mae: 11.1386\n",
            "Epoch 16/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 11.0061 - mae: 11.0061\n",
            "Epoch 17/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.8736 - mae: 10.8736\n",
            "Epoch 18/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.7411 - mae: 10.7411\n",
            "Epoch 19/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.6086 - mae: 10.6086\n",
            "Epoch 20/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.4761 - mae: 10.4761\n",
            "Epoch 21/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.3436 - mae: 10.3436\n",
            "Epoch 22/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 10.2111 - mae: 10.2111\n",
            "Epoch 23/100\n",
            "1/1 [==============================] - 0s 18ms/step - loss: 10.0786 - mae: 10.0786\n",
            "Epoch 24/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 9.9461 - mae: 9.9461\n",
            "Epoch 25/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 9.8136 - mae: 9.8136\n",
            "Epoch 26/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 9.6811 - mae: 9.6811\n",
            "Epoch 27/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 9.5486 - mae: 9.5486\n",
            "Epoch 28/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 9.4161 - mae: 9.4161\n",
            "Epoch 29/100\n",
            "1/1 [==============================] - 0s 11ms/step - loss: 9.2836 - mae: 9.2836\n",
            "Epoch 30/100\n",
            "1/1 [==============================] - 0s 11ms/step - loss: 9.1511 - mae: 9.1511\n",
            "Epoch 31/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 9.0186 - mae: 9.0186\n",
            "Epoch 32/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 8.8861 - mae: 8.8861\n",
            "Epoch 33/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 8.7536 - mae: 8.7536\n",
            "Epoch 34/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 8.6211 - mae: 8.6211\n",
            "Epoch 35/100\n",
            "1/1 [==============================] - 0s 12ms/step - loss: 8.4886 - mae: 8.4886\n",
            "Epoch 36/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 8.3561 - mae: 8.3561\n",
            "Epoch 37/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 8.2236 - mae: 8.2236\n",
            "Epoch 38/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 8.0911 - mae: 8.0911\n",
            "Epoch 39/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.9586 - mae: 7.9586\n",
            "Epoch 40/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.8261 - mae: 7.8261\n",
            "Epoch 41/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.6936 - mae: 7.6936\n",
            "Epoch 42/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.5611 - mae: 7.5611\n",
            "Epoch 43/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.4286 - mae: 7.4286\n",
            "Epoch 44/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.2961 - mae: 7.2961\n",
            "Epoch 45/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1700 - mae: 7.1700\n",
            "Epoch 46/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1644 - mae: 7.1644\n",
            "Epoch 47/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1588 - mae: 7.1588\n",
            "Epoch 48/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1531 - mae: 7.1531\n",
            "Epoch 49/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.1475 - mae: 7.1475\n",
            "Epoch 50/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.1419 - mae: 7.1419\n",
            "Epoch 51/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 7.1363 - mae: 7.1363\n",
            "Epoch 52/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1306 - mae: 7.1306\n",
            "Epoch 53/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1250 - mae: 7.1250\n",
            "Epoch 54/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1194 - mae: 7.1194\n",
            "Epoch 55/100\n",
            "1/1 [==============================] - 0s 11ms/step - loss: 7.1138 - mae: 7.1138\n",
            "Epoch 56/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.1081 - mae: 7.1081\n",
            "Epoch 57/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.1025 - mae: 7.1025\n",
            "Epoch 58/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0969 - mae: 7.0969\n",
            "Epoch 59/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0913 - mae: 7.0913\n",
            "Epoch 60/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0856 - mae: 7.0856\n",
            "Epoch 61/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0800 - mae: 7.0800\n",
            "Epoch 62/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 7.0744 - mae: 7.0744\n",
            "Epoch 63/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0688 - mae: 7.0688\n",
            "Epoch 64/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 7.0631 - mae: 7.0631\n",
            "Epoch 65/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0575 - mae: 7.0575\n",
            "Epoch 66/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0519 - mae: 7.0519\n",
            "Epoch 67/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.0463 - mae: 7.0463\n",
            "Epoch 68/100\n",
            "1/1 [==============================] - 0s 11ms/step - loss: 7.0406 - mae: 7.0406\n",
            "Epoch 69/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.0350 - mae: 7.0350\n",
            "Epoch 70/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0294 - mae: 7.0294\n",
            "Epoch 71/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0238 - mae: 7.0238\n",
            "Epoch 72/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0181 - mae: 7.0181\n",
            "Epoch 73/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0125 - mae: 7.0125\n",
            "Epoch 74/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 7.0069 - mae: 7.0069\n",
            "Epoch 75/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 7.0013 - mae: 7.0013\n",
            "Epoch 76/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9956 - mae: 6.9956\n",
            "Epoch 77/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9900 - mae: 6.9900\n",
            "Epoch 78/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9844 - mae: 6.9844\n",
            "Epoch 79/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9788 - mae: 6.9788\n",
            "Epoch 80/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9731 - mae: 6.9731\n",
            "Epoch 81/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9675 - mae: 6.9675\n",
            "Epoch 82/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9619 - mae: 6.9619\n",
            "Epoch 83/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9563 - mae: 6.9563\n",
            "Epoch 84/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 6.9506 - mae: 6.9506\n",
            "Epoch 85/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9450 - mae: 6.9450\n",
            "Epoch 86/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9394 - mae: 6.9394\n",
            "Epoch 87/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9338 - mae: 6.9338\n",
            "Epoch 88/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9281 - mae: 6.9281\n",
            "Epoch 89/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9225 - mae: 6.9225\n",
            "Epoch 90/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9169 - mae: 6.9169\n",
            "Epoch 91/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.9113 - mae: 6.9113\n",
            "Epoch 92/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.9056 - mae: 6.9056\n",
            "Epoch 93/100\n",
            "1/1 [==============================] - 0s 8ms/step - loss: 6.9000 - mae: 6.9000\n",
            "Epoch 94/100\n",
            "1/1 [==============================] - 0s 11ms/step - loss: 6.8944 - mae: 6.8944\n",
            "Epoch 95/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.8888 - mae: 6.8888\n",
            "Epoch 96/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.8831 - mae: 6.8831\n",
            "Epoch 97/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.8775 - mae: 6.8775\n",
            "Epoch 98/100\n",
            "1/1 [==============================] - 0s 15ms/step - loss: 6.8719 - mae: 6.8719\n",
            "Epoch 99/100\n",
            "1/1 [==============================] - 0s 10ms/step - loss: 6.8663 - mae: 6.8663\n",
            "Epoch 100/100\n",
            "1/1 [==============================] - 0s 9ms/step - loss: 6.8606 - mae: 6.8606\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f0065eabcd0>"
            ]
          },
          "metadata": {},
          "execution_count": 11
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1CIKSm7filgj"
      },
      "source": [
        "You might've noticed the loss value decrease from before (and keep decreasing as the number of epochs gets higher). \n",
        "\n",
        "What do you think this means for when we make a prediction with our model?\n",
        "\n",
        "How about we try predict on 17.0 again?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_YcacZsfi4zZ",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "cc6b2301-0c31-447d-9ffe-aff8df8633fb"
      },
      "source": [
        "# Remind ourselves of what X and y are\n",
        "X, y"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(<tf.Tensor: shape=(8,), dtype=float32, numpy=array([-7., -4., -1.,  2.,  5.,  8., 11., 14.], dtype=float32)>,\n",
              " <tf.Tensor: shape=(8,), dtype=float32, numpy=array([ 3.,  6.,  9., 12., 15., 18., 21., 24.], dtype=float32)>)"
            ]
          },
          "metadata": {},
          "execution_count": 12
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "e6k5V08ZivNO",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "3ab3dbff-4b9d-4e23-c4a4-5972bd690962"
      },
      "source": [
        "# Try and predict what y would be if X was 17.0\n",
        "model.predict([17.0]) # the right answer is 27.0 (y = X + 10)"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 61ms/step\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[29.499516]], dtype=float32)"
            ]
          },
          "metadata": {},
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sYi5V8ZYi_dy"
      },
      "source": [
        "Much better! \n",
        "\n",
        "We got closer this time. But we could still be better.\n",
        "\n",
        "Now we've trained a model, how could we evaluate it?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HvC98q_h6zvG"
      },
      "source": [
        "## Evaluating a model \n",
        "\n",
        "A typical workflow you'll go through when building neural networks is:\n",
        "\n",
        "```\n",
        "Build a model -> evaluate it -> build (tweak) a model -> evaulate it -> build (tweak) a model -> evaluate it...\n",
        "```\n",
        "\n",
        "The tweaking comes from maybe not building a model from scratch but adjusting an existing one.\n",
        "\n",
        "### Visualize, visualize, visualize\n",
        "\n",
        "When it comes to evaluation, you'll want to remember the words: \"visualize, visualize, visualize.\" \n",
        "\n",
        "This is because you're probably better looking at something (doing) than you are thinking about something.\n",
        "\n",
        "It's a good idea to visualize:\n",
        "* **The data** - what data are you working with? What does it look like?\n",
        "* **The model itself** - what does the architecture look like? What are the different shapes?\n",
        "* **The training of a model** - how does a model perform while it learns?\n",
        "* **The predictions of a model** - how do the predictions of a model line up against the ground truth (the original labels)?\n",
        "\n",
        "Let's start by visualizing the model.\n",
        "\n",
        "But first, we'll create a little bit of a bigger dataset and a new model we can use (it'll be the same as before, but the more practice the better).\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "srxuqbeYopns",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "e69ea103-4a9c-44e4-a8b9-fc7e7e54a707"
      },
      "source": [
        "# Make a bigger dataset\n",
        "X = np.arange(-100, 100, 4)\n",
        "X"
      ],
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([-100,  -96,  -92,  -88,  -84,  -80,  -76,  -72,  -68,  -64,  -60,\n",
              "        -56,  -52,  -48,  -44,  -40,  -36,  -32,  -28,  -24,  -20,  -16,\n",
              "        -12,   -8,   -4,    0,    4,    8,   12,   16,   20,   24,   28,\n",
              "         32,   36,   40,   44,   48,   52,   56,   60,   64,   68,   72,\n",
              "         76,   80,   84,   88,   92,   96])"
            ]
          },
          "metadata": {},
          "execution_count": 14
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "pQcC0nSko3kJ",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "798785e6-2a92-43aa-b09a-4fc47a7ef5bf"
      },
      "source": [
        "# Make labels for the dataset (adhering to the same pattern as before)\n",
        "y = np.arange(-90, 110, 4)\n",
        "y"
      ],
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([-90, -86, -82, -78, -74, -70, -66, -62, -58, -54, -50, -46, -42,\n",
              "       -38, -34, -30, -26, -22, -18, -14, -10,  -6,  -2,   2,   6,  10,\n",
              "        14,  18,  22,  26,  30,  34,  38,  42,  46,  50,  54,  58,  62,\n",
              "        66,  70,  74,  78,  82,  86,  90,  94,  98, 102, 106])"
            ]
          },
          "metadata": {},
          "execution_count": 15
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KNIw5tgGpKjb"
      },
      "source": [
        "Since $y=X+10$, we could make the labels like so:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ACgbmrAOpJwW",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "3543a815-2db7-4f22-af64-e7e14e0e2c83"
      },
      "source": [
        "# Same result as above\n",
        "y = X + 10\n",
        "y"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([-90, -86, -82, -78, -74, -70, -66, -62, -58, -54, -50, -46, -42,\n",
              "       -38, -34, -30, -26, -22, -18, -14, -10,  -6,  -2,   2,   6,  10,\n",
              "        14,  18,  22,  26,  30,  34,  38,  42,  46,  50,  54,  58,  62,\n",
              "        66,  70,  74,  78,  82,  86,  90,  94,  98, 102, 106])"
            ]
          },
          "metadata": {},
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ax3MnQDupeBp"
      },
      "source": [
        "## Split data into training/test set\n",
        "\n",
        "One of the other most common and important steps in a machine learning project is creating a training and test set (and when required, a validation set).\n",
        "\n",
        "Each set serves a specific purpose:\n",
        "* **Training set** - the model learns from this data, which is typically 70-80% of the total data available (like the course materials you study during the semester).\n",
        "* **Validation set** - the model gets tuned on this data, which is typically 10-15% of the total data available (like the practice exam you take before the final exam).\n",
        "* **Test set** - the model gets evaluated on this data to test what it has learned, it's typically 10-15% of the total data available (like the final exam you take at the end of the semester).\n",
        "\n",
        "For now, we'll just use a training and test set, this means we'll have a dataset for our model to learn on as well as be evaluated on.\n",
        "\n",
        "We can create them by splitting our `X` and `y` arrays.\n",
        "\n",
        "> 🔑 **Note:** When dealing with real-world data, this step is typically done right at the start of a project (the test set should always be kept separate from all other data). We want our model to learn on training data and then evaluate it on test data to get an indication of how well it **generalizes** to unseen examples."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5G0RDMnZrgvK",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "db23e775-8a72-4622-fca7-bd40ba567edd"
      },
      "source": [
        "# Check how many samples we have\n",
        "len(X)"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "50"
            ]
          },
          "metadata": {},
          "execution_count": 17
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4Q9ptcQkrGfO",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "164c9b80-9447-4919-a07d-eb52d2a7d425"
      },
      "source": [
        "# Split data into train and test sets\n",
        "X_train = X[:40] # first 40 examples (80% of data)\n",
        "y_train = y[:40]\n",
        "\n",
        "X_test = X[40:] # last 10 examples (20% of data)\n",
        "y_test = y[40:]\n",
        "\n",
        "len(X_train), len(X_test)"
      ],
      "execution_count": 18,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(40, 10)"
            ]
          },
          "metadata": {},
          "execution_count": 18
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Rz2cIdECsLH5"
      },
      "source": [
        "## Visualizing the data\n",
        "\n",
        "Now we've got our training and test data, it's a good idea to visualize it.\n",
        "\n",
        "Let's plot it with some nice colours to differentiate what's what."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "os30CXBHsOAH",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 599
        },
        "outputId": "3f07137f-0682-41d3-cb98-0f68eac9792d"
      },
      "source": [
        "plt.figure(figsize=(10, 7))\n",
        "# Plot training data in blue\n",
        "plt.scatter(X_train, y_train, c='b', label='Training data')\n",
        "# Plot test data in green\n",
        "plt.scatter(X_test, y_test, c='g', label='Testing data')\n",
        "# Show the legend\n",
        "plt.legend();"
      ],
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1000x700 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAJGCAYAAACdj47VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABcHElEQVR4nO3deXxU9b3/8fdkkAiFSRSBDJlhcalQ96XlYh0NVypUq9Ex1avWrRa7oBLR1np/1q3txbp1orV1B++ttmJ6au2GF1B0VERKpdY2UrFg4nCAW5UEtbKcnN8fX2eayQRmQmaf1/PxmIec7/mc4ZtxannzPef78biu6woAAAAAKkRVoScAAAAAAPlECAIAAABQUQhBAAAAACoKIQgAAABARSEEAQAAAKgohCAAAAAAFYUQBAAAAKCiDCr0BAaqu7tb69ev1/Dhw+XxeAo9HQAAAAAF4rqutmzZojFjxqiqaufrPSUfgtavX69gMFjoaQAAAAAoEh0dHQoEAjs9X/IhaPjw4ZLMD+rz+Qo8GwAAAACF0tXVpWAwmMgIO1PyISh+C5zP5yMEAQAAAEj7mAwbIwAAAACoKIQgAAAAABWFEAQAAACgopT8M0GZchxH27dvL/Q0UMT22GMPeb3eQk8DAAAAOVb2Ich1XW3YsEGbN28u9FRQAmpra1VXV0fPKQAAgDJW9iEoHoBGjRqloUOH8odb9Ml1XX344YfatGmTJMnv9xd4RgAAAMiVsg5BjuMkAtCIESMKPR0UuSFDhkiSNm3apFGjRnFrHAAAQJkq640R4s8ADR06tMAzQamIf1d4fgwAAKB8lXUIiuMWOGSK7woAAED5q4gQBAAAAABxhKAKMX78eEUikYzrly5dKo/HU5Bd9ebPn6/a2tq8/74AAACoDISgIuPxeHb5uuGGG3brfVesWKFLLrkk4/pjjjlGtm2rpqZmt36/fOtvyAMAAEDlKuvd4bLFcaRoVLJtye+XQiEpVxuH2bad+PVjjz2m6667TqtXr06MDRs2LPFr13XlOI4GDUr/r3HkyJH9msfgwYNVV1fXr2sAAACAUsBKUBqWJY0fL02dKp1zjvnn+PFmPBfq6uoSr5qaGnk8nsTx66+/ruHDh+v3v/+9jjrqKFVXV+v555/Xm2++qcbGRo0ePVrDhg3Tpz/9aS1evDjpfXuvlHg8Hj3wwAM6/fTTNXToUB1wwAF68sknE+d73w4Xv0Xtqaee0qRJkzRs2DDNmDEjKbTt2LFDl19+uWprazVixAhdffXVuuCCC3Taaaft8meeP3++xo4dq6FDh+r000/XO++8k3Q+3c/X0NCgt956S1dccUVixUyS3nnnHZ199tmqr6/X0KFDdcghh+hnP/tZf/51AAAAoAwRgnbBsqSmJuntt5PHYzEznqsglM63v/1t3XzzzWpra9Ohhx6q999/XyeddJKWLFmiV155RTNmzNApp5yi9vb2Xb7PjTfeqDPPPFOvvvqqTjrpJJ177rl69913d1r/4Ycf6rbbbtP//M//6LnnnlN7e7uuuuqqxPkf/OAHeuSRRzRv3jy98MIL6urq0hNPPLHLOSxfvlwXX3yxLr30Uq1atUpTp07V9773vaSadD+fZVkKBAK66aabZNt2Iph99NFHOuqoo/Tb3/5Wr732mi655BKdd955evnll3c5JwAAAJQ5t8R1dna6ktzOzs6Uc//85z/dv/71r+4///nPfr/vjh2uGwi4rtT3y+Nx3WDQ1OXKvHnz3JqamsTxM88840pyn3jiibTXHnTQQe5dd92VOB43bpz7wx/+MHEsyb322msTx++//74ryf3973+f9Hu99957iblIctesWZO45u6773ZHjx6dOB49erR76623Jo537Njhjh071m1sbNzpPM8++2z3pJNOSho766yzkn7u3fn5dubkk092r7zyyp2eH8h3BgAAAIW1q2zQEytBOxGNpq4A9eS6UkeHqcu3o48+Oun4/fff11VXXaVJkyaptrZWw4YNU1tbW9qVoEMPPTTx60984hPy+XzatGnTTuuHDh2q/fbbL3Hs9/sT9Z2dndq4caM+85nPJM57vV4dddRRu5xDW1ubJk+enDQ2ZcqUrPx8juPou9/9rg455BDtvffeGjZsmJ566qm01wEAAKC8sTHCTvR41CUrddn0iU98Iun4qquu0qJFi3Tbbbdp//3315AhQ9TU1KRt27bt8n322GOPpGOPx6Pu7u5+1buu28/Z99/u/ny33nqrWlpaFIlEdMghh+gTn/iEmpub014HAACAzDjdjqLtUdlbbPmH+xUaG5K3Kkc7iGURIWgn/P7s1uXSCy+8oAsvvFCnn366JLNysm7durzOoaamRqNHj9aKFSt03HHHSTIrMX/84x91+OGH7/S6SZMmafny5UljL730UtJxJj/f4MGD5ThOynWNjY360pe+JEnq7u7W3/72N33qU5/anR8RAAAAPVhtlmYvnK23u/51+1TAF1DLjBaFJ4ULOLP0uB1uJ0IhKRCQPt5oLIXHIwWDpq7QDjjgAFmWpVWrVulPf/qTzjnnnF2u6OTKZZddprlz5+pXv/qVVq9erdmzZ+u9995L7NbWl8svv1wLFy7UbbfdpjfeeEM/+tGPtHDhwqSaTH6+8ePH67nnnlMsFtM//vGPxHWLFi3Siy++qLa2Nn31q1/Vxo0bs/+DAwAAVBirzVLTgqakACRJsa6YmhY0yWor0A5iGSIE7YTXK7W0mF/3/jN8/DgSyV2/oP644447tNdee+mYY47RKaecounTp+vII4/M+zyuvvpqnX322Tr//PM1ZcoUDRs2TNOnT9eee+6502v+7d/+Tffff79aWlp02GGH6X//93917bXXJtVk8vPddNNNWrdunfbbb79ET6Rrr71WRx55pKZPn66GhgbV1dWl3a4bAAAAu+Z0O5q9cLZcpT4WER9rXtgsp9tJOV8sPG4+HurIoa6uLtXU1Kizs1M+ny/p3EcffaS1a9dqwoQJu/yD+K5YljR7dvImCcGgCUDh4l7lK7ju7m5NmjRJZ555pr773e8WejoZycZ3BgAAoJwtXbdUUx+emrbumQueUcP4htxPqIddZYOeeCYojXBYamw0u8DZtnkGKBQqjhWgYvPWW2/pf//3f3X88cdr69at+tGPfqS1a9fqnHPOKfTUAAAAkCX2lsx2Bsu0rhAIQRnweqWGhkLPovhVVVVp/vz5uuqqq+S6rg4++GAtXrxYkyZNKvTUAAAAkCX+4ZntDJZpXSEQgpA1wWBQL7zwQqGnAQAAgBwKjQ0p4Aso1hXr87kgjzwK+AIKjS2CHcR2go0RAAAAAGTMW+VVywyzg5hHyTuIxY8jMyJF3S+IEAQAAACgX8KTwmo9s1X1vvqk8YAvoNYzW4u+TxC3wwEAAAAVzOl2FG2Pyt5iyz/cr9DYUEarOOFJYTUe2Lhb1xYaIQgAAACoUFabpdkLZyc1PQ34AmqZ0ZLRao63ypv3bbCzgdvhAAAAgApktVlqWtCUFIAkKdYVU9OCJlltVoFmlnuEIAAAAKDCON2OZi+c3efubvGx5oXNcrqdfE8tLwhBFe6GG27Q4YcfXpDf+8ILL9Rpp51WkN8bAACgkkXboykrQD25ctXR1aFoezSPs8ofQlCR8Xg8u3zdcMMNA3rvJ554Imnsqquu0pIlSwY26TxZt26dPB6PVq1aVeipAAAAlDR7i53VulKz2yHoueee0ymnnKIxY8b0+Ydr13V13XXXye/3a8iQIZo2bZreeOONpJp3331X5557rnw+n2pra3XxxRfr/fff390p5YzT7WjpuqX62Z9/pqXrluZ0WdC27cQrEonI5/MljV111VVZ/f2GDRumESNGZPU9AQAAUNz8w/1ZrSs1ux2CPvjgAx122GG6++67+zx/yy236M4779Q999yj5cuX6xOf+ISmT5+ujz76KFFz7rnn6i9/+YsWLVqk3/zmN3ruued0ySWX7O6UcsJqszS+ZbymPjxV51jnaOrDUzW+ZXzOHhSrq6tLvGpqauTxeJLGfv7zn2vSpEnac889NXHiRP34xz9OXLtt2zZdeuml8vv92nPPPTVu3DjNnTtXkjR+/HhJ0umnny6Px5M47n07XPwWtdtuu01+v18jRozQrFmztH379kSNbds6+eSTNWTIEE2YMEGPPvqoxo8fr0gkstOfy3EczZkzR7W1tRoxYoS+9a1vyXWT70FduHChjj322ETNF77wBb355puJ8xMmTJAkHXHEEfJ4PGpoaJAkrVixQp/73Oe0zz77qKamRscff7z++Mc/9vejBwAAqBihsSEFfIGUZqdxHnkU9AUVGhvK88zyY7dD0Oc//3l973vf0+mnn55yznVdRSIRXXvttWpsbNShhx6q//7v/9b69esTK0ZtbW1auHChHnjgAU2ePFnHHnus7rrrLv385z/X+vXrd/sHyqZi2zHjkUce0XXXXafvf//7amtr03/913/pO9/5jh5++GFJ0p133qknn3xSCxYs0OrVq/XII48kws6KFSskSfPmzZNt24njvjzzzDN688039cwzz+jhhx/W/PnzNX/+/MT5888/X+vXr9fSpUv1i1/8Qvfdd582bdq0y7nffvvtmj9/vh566CE9//zzevfdd/XLX/4yqeaDDz7QnDlz9Ic//EFLlixRVVWVTj/9dHV3d0uSXn75ZUnS4sWLZdu2LMt8/lu2bNEFF1yg559/Xi+99JIOOOAAnXTSSdqyZUvmHy4AAEAF8VZ51TKjRZJSglD8ODIjUhI9f3ZHTvoErV27Vhs2bNC0adMSYzU1NZo8ebKWLVum//iP/9CyZctUW1uro48+OlEzbdo0VVVVafny5X2GK0naunWrtm7dmjju6urKxY+QdscMjzxqXtisxgMb8/bluP7663X77bcrHDZ7tk+YMEF//etfde+99+qCCy5Qe3u7DjjgAB177LHyeDwaN25c4tqRI0dKkmpra1VXV7fL32evvfbSj370I3m9Xk2cOFEnn3yylixZopkzZ+r111/X4sWLtWLFisS/uwceeEAHHHDALt8zEonommuuScz9nnvu0VNPPZVUc8YZZyQdP/TQQxo5cqT++te/6uCDD078DCNGjEj6Gf793/896br77rtPtbW1evbZZ/WFL3xhl/MCAACoVOFJYbWe2dpnn6DIjEhGfYJKVU5C0IYNGyRJo0ePThofPXp04tyGDRs0atSo5MkMGqS99947UdOXuXPn6sYbb8zyjFP1Z8eMfDSI+uCDD/Tmm2/q4osv1syZMxPjO3bsUE1NjSRzK9vnPvc5HXjggZoxY4a+8IUv6MQTT+z373XQQQfJ6/1XsPP7/frzn/8sSVq9erUGDRqkI488MnF+//3311577bXT9+vs7JRt25o8eXJibNCgQTr66KOTbol74403dN1112n58uX6xz/+kVgBam9v18EHH7zT99+4caOuvfZaLV26VJs2bZLjOPrwww/V3t7e758dAACgVDndjqLtUdlbbPmH+xUaG0r7l/XhSWE1HtjY7+tKXU5CUC5dc801mjNnTuK4q6tLwWAw679Pse2YEd8w4v77708KE5ISgeXII4/U2rVr9fvf/16LFy/WmWeeqWnTpqm1tbVfv9cee+yRdOzxeBKBJJdOOeUUjRs3Tvfff7/GjBmj7u5uHXzwwdq2bdsur7vgggv0zjvvqKWlRePGjVN1dbWmTJmS9joAAIByYbVZfa7otMxoSbui463y5uUv9YtJTrbIjt+qtHHjxqTxjRs3Js7V1dWlPEeyY8cOvfvuu7u8Xau6ulo+ny/plQvFtmPG6NGjNWbMGP3973/X/vvvn/SKbxggST6fT2eddZbuv/9+PfbYY/rFL36hd999V5IJN44zsJ3tDjzwQO3YsUOvvPJKYmzNmjV67733dnpNTU2N/H6/li9fnhjbsWOHVq5cmTh+5513tHr1al177bU64YQTNGnSpJT3HDx4sCSl/Awv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dPLJJ2vbtm168cUX9fDDD2v+/Pm67rrrEjVr167VySefrKlTp2rVqlVqbm7WV77yFT311FP5+jFKyjHHHCPbtpNeX/nKVzRhwgQdffTRSbWLFy9OqjvqqKMKNOvSddNNNyV9hpdddlniXFdXl0488USNGzdOK1eu1K233qobbrhB9913XwFnXFpef/11dXd3695779Vf/vIX/fCHP9Q999yj//zP/0yp5fu8+x577DHNmTNH119/vf74xz/qsMMO0/Tp07Vp06ZCT61kPfvss5o1a5ZeeuklLVq0SNu3b9eJJ56oDz74IKlu5syZSd9b/qKk/w466KCkz/D5559PnLviiiv061//Wo8//rieffZZrV+/XuFwuICzLU0rVqxI+owXLVokSfriF7+YqOG73D8ffPCBDjvsMN199919nr/lllt055136p577tHy5cv1iU98QtOnT9dHH32UqDn33HP1l7/8RYsWLdJvfvMbPffcc7rkkkuyO1EXAzJv3jy3pqYmZfx3v/udW1VV5W7YsCEx9pOf/MT1+Xzu1q1bXdd13W9961vuQQcdlHTdWWed5U6fPj2ncy4X27Ztc0eOHOnedNNNibG1a9e6ktxXXnmlcBMrA+PGjXN/+MMf7vT8j3/8Y3evvfZKfJdd13Wvvvpq98ADD8zD7MrXLbfc4k6YMCFxzPd54D7zmc+4s2bNShw7juOOGTPGnTt3bgFnVV42bdrkSnKfffbZxNjxxx/vzp49u3CTKgPXX3+9e9hhh/V5bvPmze4ee+zhPv7444mxtrY2V5K7bNmyPM2wPM2ePdvdb7/93O7ubtd1+S4PlCT3l7/8ZeK4u7vbraurc2+99dbE2ObNm93q6mr3Zz/7meu6rvvXv/7VleSuWLEiUfP73//e9Xg8biwWy9rcWAnKkWXLlumQQw7R6NGjE2PTp09XV1eX/vKXvyRqpk2blnTd9OnTtWzZsrzOtVQ9+eSTeuedd3TRRRelnDv11FM1atQoHXvssXryyScLMLvSd/PNN2vEiBE64ogjdOuttybdyrls2TIdd9xxGjx4cGJs+vTpWr16td57771CTLcsdHZ2au+9904Z5/u8e7Zt26aVK1cm/Xe2qqpK06ZN47+zWdTZ2SlJKd/dRx55RPvss48OPvhgXXPNNfrwww8LMb2S9sYbb2jMmDHad999de6556q9vV2StHLlSm3fvj3puz1x4kSNHTuW7/YAbNu2TT/96U/15S9/WR6PJzHOdzl71q5dqw0bNiR9d2tqajR58uTEd3fZsmWqra1Nustn2rRpqqqq0vLly7M2l0FZeyck2bBhQ1IAkpQ43rBhwy5rurq69M9//lNDhgzJz2RL1IMPPqjp06crEAgkxoYNG6bbb79dn/3sZ1VVVaVf/OIXOu200/TEE0/o1FNPLeBsS8vll1+uI488UnvvvbdefPFFXXPNNbJtW3fccYck892dMGFC0jU9v9977bVX3udc6tasWaO77rpLt912W2KM7/PA/OMf/5DjOH3+d/b1118v0KzKS3d3t5qbm/XZz35WBx98cGL8nHPO0bhx4zRmzBi9+uqruvrqq7V69WpZllXA2ZaWyZMna/78+TrwwANl27ZuvPFGhUIhvfbaa9qwYYMGDx6c8kzy6NGjE3/GQP898cQT2rx5sy688MLEGN/l7Ip/P/v673LPPx+PGjUq6fygQYO09957Z/X7TQjq4dvf/rZ+8IMf7LKmra0t6cFEDNzufO5vv/22nnrqKS1YsCCpbp999tGcOXMSx5/+9Ke1fv163XrrrRX/h8b+fM49P8NDDz1UgwcP1le/+lXNnTtX1dXVuZ5qSdud73MsFtOMGTP0xS9+UTNnzkyM831GsZs1a5Zee+21pGdVJCXdu3/IIYfI7/frhBNO0Jtvvqn99tsv39MsSZ///OcTvz700EM1efJkjRs3TgsWLOAvSXPkwQcf1Oc//3mNGTMmMcZ3uXwRgnq48sork9J/X/bdd9+M3quuri5lB6L4ri11dXWJf/beyWXjxo3y+XwV9R+43fnc582bpxEjRmT0B8HJkycnHnSsZAP5fk+ePFk7duzQunXrdOCBB+70uyv96/tdqfr7Oa9fv15Tp07VMccck9HGEnyfM7fPPvvI6/X2+V2t9O9pNlx66aWJB5Z7rsj3ZfLkyZLMiid/cNw9tbW1+uQnP6k1a9boc5/7nLZt26bNmzcnrQbx3d59b731lhYvXpx2hYfv8sDEv58bN26U3+9PjG/cuFGHH354oqb35jU7duzQu+++m9XvNyGoh5EjR2rkyJFZea8pU6bo+9//vjZt2pRY0lu0aJF8Pp8+9alPJWp+97vfJV23aNEiTZkyJStzKBX9/dxd19W8efN0/vnna4899khbv2rVqqT/oVWqgXy/V61apaqqqsR3ecqUKfp//+//afv27Yl/B4sWLdKBBx5Y8bfC9edzjsVimjp1qo466ijNmzdPVVXpH9Pk+5y5wYMH66ijjtKSJUt02mmnSTK3by1ZskSXXnppYSdXwlzX1WWXXaZf/vKXWrp0acqtsX1ZtWqVJPHdHYD3339fb775ps477zwdddRR2mOPPbRkyRKdccYZkqTVq1ervb294v4MkS3z5s3TqFGjdPLJJ++yju/ywEyYMEF1dXVasmRJIvR0dXVp+fLliR2Xp0yZos2bN2vlypWJ3VCffvppdXd3J0JoVmRti4UK89Zbb7mvvPKKe+ONN7rDhg1zX3nlFfeVV15xt2zZ4rqu6+7YscM9+OCD3RNPPNFdtWqVu3DhQnfkyJHuNddck3iPv//97+7QoUPdb37zm25bW5t79913u16v1124cGGhfqySsHjxYleS29bWlnJu/vz57qOPPuq2tbW5bW1t7ve//323qqrKfeihhwow09L04osvuj/84Q/dVatWuW+++ab705/+1B05cqR7/vnnJ2o2b97sjh492j3vvPPc1157zf35z3/uDh061L333nsLOPPS8vbbb7v777+/e8IJJ7hvv/22a9t24hXH93ngfv7zn7vV1dXu/Pnz3b/+9a/uJZdc4tbW1ibt3In++frXv+7W1NS4S5cuTfrefvjhh67ruu6aNWvcm266yf3DH/7grl271v3Vr37l7rvvvu5xxx1X4JmXliuvvNJdunSpu3btWveFF15wp02b5u6zzz7upk2bXNd13a997Wvu2LFj3aefftr9wx/+4E6ZMsWdMmVKgWddmhzHcceOHeteffXVSeN8l3fPli1bEn8uluTecccd7iuvvOK+9dZbruu67s033+zW1ta6v/rVr9xXX33VbWxsdCdMmOD+85//TLzHjBkz3COOOMJdvny5+/zzz7sHHHCAe/bZZ2d1noSg3XTBBRe4klJezzzzTKJm3bp17uc//3l3yJAh7j777ONeeeWV7vbt25Pe55lnnnEPP/xwd/Dgwe6+++7rzps3L78/SAk6++yz3WOOOabPc/Pnz3cnTZrkDh061PX5fO5nPvOZpC1Ekd7KlSvdyZMnuzU1Ne6ee+7pTpo0yf2v//ov96OPPkqq+9Of/uQee+yxbnV1tVtfX+/efPPNBZpxaZo3b16f/w3p+XdTfJ+z46677nLHjh3rDh482P3MZz7jvvTSS4WeUknb2fc2/v9f7e3t7nHHHefuvffebnV1tbv//vu73/zmN93Ozs7CTrzEnHXWWa7f73cHDx7s1tfXu2eddZa7Zs2axPl//vOf7je+8Q13r732cocOHeqefvrpSX+Jgsw99dRTriR39erVSeN8l3fPM8880+d/Iy644ALXdc022d/5znfc0aNHu9XV1e4JJ5yQ8tm/88477tlnn+0OGzbM9fl87kUXXZRYaMgWj+u6bvbWlQAAAACguNEnCAAAAEBFIQQBAAAAqCiEIAAAAAAVhRAEAAAAoKIQggAAAABUFEIQAAAAgIpCCAIAAABQUQhBAAAAACoKIQgAAABARSEEAQAAAKgohCAAAAAAFeX/A3b98HJJqYD3AAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cxRcHZFgtS_B"
      },
      "source": [
        "Beautiful! Any time you can visualize your data, your model, your anything, it's a good idea. \n",
        "\n",
        "With this graph in mind, what we'll be trying to do is build a model which learns the pattern in the blue dots (`X_train`) to draw the green dots (`X_test`).\n",
        "\n",
        "Time to build a model. We'll make the exact same one from before (the one we trained for longer)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4qpe0eSStSm-"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Create a model (same as above)\n",
        "model = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile model (same as above)\n",
        "model.compile(loss=tf.keras.losses.mae,\n",
        "              optimizer=tf.keras.optimizers.SGD(),\n",
        "              metrics=[\"mae\"])\n",
        "\n",
        "# Fit model (same as above)\n",
        "#model.fit(X_train, y_train, epochs=100) # commented out on purpose (not fitting it just yet)"
      ],
      "execution_count": 20,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hc2RHCCfqlAc"
      },
      "source": [
        "## Visualizing the model\n",
        "\n",
        "After you've built a model, you might want to take a look at it (especially if you haven't built many before).\n",
        "\n",
        "You can take a look at the layers and shapes of your model by calling [`summary()`](https://www.tensorflow.org/api_docs/python/tf/keras/Model#summary) on it.\n",
        "\n",
        "> 🔑 **Note:** Visualizing a model is particularly helpful when you run into input and output shape mismatches."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OlgJj0cFwChH",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 347
        },
        "outputId": "083d7b9e-bb15-4307-ee55-4d07aea7547a"
      },
      "source": [
        "# Doesn't work (model not fit/built)\n",
        "model.summary()"
      ],
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "error",
          "ename": "ValueError",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-22-7d09d31d4e66>\u001b[0m in \u001b[0;36m<cell line: 2>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;31m# Doesn't work (model not fit/built)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msummary\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/keras/engine/training.py\u001b[0m in \u001b[0;36msummary\u001b[0;34m(self, line_length, positions, print_fn, expand_nested, show_trainable, layer_range)\u001b[0m\n\u001b[1;32m   3227\u001b[0m         \"\"\"\n\u001b[1;32m   3228\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuilt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3229\u001b[0;31m             raise ValueError(\n\u001b[0m\u001b[1;32m   3230\u001b[0m                 \u001b[0;34m\"This model has not yet been built. \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3231\u001b[0m                 \u001b[0;34m\"Build the model first by calling `build()` or by calling \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mValueError\u001b[0m: This model has not yet been built. Build the model first by calling `build()` or by calling the model on a batch of data."
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SJj6KLe8xsyF"
      },
      "source": [
        "Ahh, the cell above errors because we haven't fit or built our model.\n",
        "\n",
        "We also haven't told it what input shape it should be expecting.\n",
        "\n",
        "Remember above, how we discussed the input shape was just one number?\n",
        "\n",
        "We can let our model know the input shape of our data using the `input_shape` parameter to the first layer (usually if `input_shape` isn't defined, Keras tries to figure it out automatically)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zMXKFtFBuWgJ"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Create a model (same as above)\n",
        "model = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1, input_shape=[1]) # define the input_shape to our model\n",
        "])\n",
        "\n",
        "# Compile model (same as above)\n",
        "model.compile(loss=tf.keras.losses.mae,\n",
        "              optimizer=tf.keras.optimizers.SGD(),\n",
        "              metrics=[\"mae\"])"
      ],
      "execution_count": 23,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "24Q325x2yCoi",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "3c29ddf8-7098-40b9-e58c-5b874526bd46"
      },
      "source": [
        "# This will work after specifying the input shape\n",
        "model.summary()"
      ],
      "execution_count": 24,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model: \"sequential_3\"\n",
            "_________________________________________________________________\n",
            " Layer (type)                Output Shape              Param #   \n",
            "=================================================================\n",
            " dense_3 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            "=================================================================\n",
            "Total params: 2\n",
            "Trainable params: 2\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jdurWKlryl6b"
      },
      "source": [
        "Calling `summary()` on our model shows us the layers it contains, the output shape and the number of parameters.\n",
        "* **Total params** - total number of parameters in the model.\n",
        "* **Trainable parameters** - these are the parameters (patterns) the model can update as it trains.\n",
        "* **Non-trainable parameters** - these parameters aren't updated during training (this is typical when you bring in the already learned patterns from other models during transfer learning).\n",
        "\n",
        "> 📖 **Resource:** For a more in-depth overview of the trainable parameters within a layer, check out [MIT's introduction to deep learning video](https://youtu.be/njKP3FqW3Sk).\n",
        "\n",
        "> 🛠 **Exercise:** Try playing around with the number of hidden units in the `Dense` layer (e.g. `Dense(2)`, `Dense(3)`). How does this change the Total/Trainable params? Investigate what's causing the change.\n",
        "\n",
        "For now, all you need to think about these parameters is that their learnable patterns in the data.\n",
        "\n",
        "Let's fit our model to the training data."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-Kywg4q9u051",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "7a071bcb-9281-44e9-cda9-b3b5e1165bbd"
      },
      "source": [
        "# Fit the model to the training data\n",
        "model.fit(X_train, y_train, epochs=100, verbose=0) # verbose controls how much gets output"
      ],
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f0065dd80d0>"
            ]
          },
          "metadata": {},
          "execution_count": 25
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-jWuOwj961ri",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a0bc6b4c-2ee6-41b0-d8c8-c332cdc976d9"
      },
      "source": [
        "# Check the model summary\n",
        "model.summary()"
      ],
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model: \"sequential_3\"\n",
            "_________________________________________________________________\n",
            " Layer (type)                Output Shape              Param #   \n",
            "=================================================================\n",
            " dense_3 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            "=================================================================\n",
            "Total params: 2\n",
            "Trainable params: 2\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RrrkHEkMYh5A"
      },
      "source": [
        "Alongside summary, you can also view a 2D plot of the model using [`plot_model()`](https://www.tensorflow.org/api_docs/python/tf/keras/utils/plot_model)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "liIg5WqDfdK4",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 201
        },
        "outputId": "cd8d3811-4d9d-4809-909f-b132847e68f3"
      },
      "source": [
        "from tensorflow.keras.utils import plot_model\n",
        "\n",
        "plot_model(model, show_shapes=True)"
      ],
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<IPython.core.display.Image object>"
            ]
          },
          "metadata": {},
          "execution_count": 27
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ygw7V8OVYxQS"
      },
      "source": [
        "In our case, the model we used only has an input and an output but visualizing more complicated models can be very helpful for debugging."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gebj2eptqwg8"
      },
      "source": [
        "## Visualizing the predictions\n",
        "\n",
        "Now we've got a trained model, let's visualize some predictions.\n",
        "\n",
        "To visualize predictions, it's always a good idea to plot them against the ground truth labels.\n",
        "\n",
        "Often you'll see this in the form of `y_test` vs. `y_pred` (ground truth vs. predictions).\n",
        "\n",
        "First, we'll make some predictions on the test data (`X_test`), remember the model has never seen the test data."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RRzj7LJMYftb",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a7ff5799-23ae-4c4c-bc26-f3d1ad24dffb"
      },
      "source": [
        "# Make predictions\n",
        "y_preds = model.predict(X_test)"
      ],
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 45ms/step\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_hKpW-KOZiAW",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "ad0bc00f-5906-433b-cb95-7730b29d2ba7"
      },
      "source": [
        "# View the predictions\n",
        "y_preds"
      ],
      "execution_count": 29,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[44.544697],\n",
              "       [47.427135],\n",
              "       [50.309574],\n",
              "       [53.192013],\n",
              "       [56.07445 ],\n",
              "       [58.95689 ],\n",
              "       [61.839325],\n",
              "       [64.72176 ],\n",
              "       [67.60421 ],\n",
              "       [70.48664 ]], dtype=float32)"
            ]
          },
          "metadata": {},
          "execution_count": 29
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aPRaFncaZnT-"
      },
      "source": [
        "Okay, we get a list of numbers but how do these compare to the ground truth labels?\n",
        "\n",
        "Let's build a plotting function to find out.\n",
        "\n",
        "> 🔑 **Note:** If you think you're going to be visualizing something a lot, it's a good idea to functionize it so you can use it later."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "56euC69rZvNJ"
      },
      "source": [
        "def plot_predictions(train_data=X_train, \n",
        "                     train_labels=y_train, \n",
        "                     test_data=X_test, \n",
        "                     test_labels=y_test, \n",
        "                     predictions=y_preds):\n",
        "  \"\"\"\n",
        "  Plots training data, test data and compares predictions.\n",
        "  \"\"\"\n",
        "  plt.figure(figsize=(10, 7))\n",
        "  # Plot training data in blue\n",
        "  plt.scatter(train_data, train_labels, c=\"b\", label=\"Training data\")\n",
        "  # Plot test data in green\n",
        "  plt.scatter(test_data, test_labels, c=\"g\", label=\"Testing data\")\n",
        "  # Plot the predictions in red (predictions were made on the test data)\n",
        "  plt.scatter(test_data, predictions, c=\"r\", label=\"Predictions\")\n",
        "  # Show the legend\n",
        "  plt.legend();"
      ],
      "execution_count": 30,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Fug5_B6Ab7Ah",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 599
        },
        "outputId": "dd044464-faf2-4570-fc82-8bd22fb4779b"
      },
      "source": [
        "plot_predictions(train_data=X_train,\n",
        "                 train_labels=y_train,\n",
        "                 test_data=X_test,\n",
        "                 test_labels=y_test,\n",
        "                 predictions=y_preds)"
      ],
      "execution_count": 31,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1000x700 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAJGCAYAAACdj47VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABjr0lEQVR4nO3dfXyT5b3H8W8aoILQVh4bmvCgKDDxETcOzGg5MkGdFmOnR5zC5nBzoK3oppzjfNp2cD6t1bmpU4tnUyfr7jHmHA5QNCogYzLmLAis2BoCbCotojyl9/njNlnTtE3a5jmf9+vVF9zX/Ut6Nc1cflzX9fvZTNM0BQAAAAA5Ii/VEwAAAACAZCIJAgAAAJBTSIIAAAAA5BSSIAAAAAA5hSQIAAAAQE4hCQIAAACQU0iCAAAAAOSUXqmeQE+1tLRo586dGjBggGw2W6qnAwAAACBFTNPUvn37NHz4cOXldbzek/FJ0M6dO+VyuVI9DQAAAABporGxUU6ns8P7GZ8EDRgwQJL1gxYUFKR4NgAAAABSpbm5WS6XK5QjdCTjk6DgFriCggKSIAAAAABRj8lQGAEAAABATiEJAgAAAJBTSIIAAAAA5JSMPxMUq0AgoMOHD6d6GkhjvXv3lt1uT/U0AAAAkGBZnwSZpqldu3Zp7969qZ4KMkBRUZGKi4vpOQUAAJDFsj4JCiZAQ4cOVb9+/fhwi3aZpqlPPvlEe/bskSQ5HI4UzwgAAACJktVJUCAQCCVAgwYNSvV0kOb69u0rSdqzZ4+GDh3K1jgAAIAsldWFEYJngPr165fimSBTBN8rnB8DAADIXlmdBAWxBQ6x4r0CAACQ/XIiCQIAAACAIJKgHDFq1ChVVVXFHL969WrZbLaUVNVbvHixioqKkv59AQAAkBtIgtKMzWbr9OuOO+7o1vOuX79e11xzTczxU6ZMkd/vV2FhYbe+X7J1NckDAABA7srq6nDxEghIXq/k90sOh+R2S4kqHOb3+0N/f+6553Tbbbdpy5YtobH+/fuH/m6apgKBgHr1iv5rHDJkSJfm0adPHxUXF3fpMQAAAEAmYCUoCsOQRo2Spk6VZs2y/hw1yhpPhOLi4tBXYWGhbDZb6Hrz5s0aMGCA/vjHP2rixInKz8/Xa6+9pu3bt6usrEzDhg1T//799fnPf14rV64Me962KyU2m02PP/64Lr74YvXr10/HH3+8li1bFrrfdjtccIvaiy++qPHjx6t///6aMWNGWNJ25MgRXX/99SoqKtKgQYN08803a/bs2Zo5c2anP/PixYs1YsQI9evXTxdffLE++OCDsPvRfr7S0lK99957uuGGG0IrZpL0wQcf6PLLL1dJSYn69eunk046Sc8++2xXfh0AAADIQiRBnTAMqbxcev/98HGfzxpPVCIUzS233KK7775bdXV1Ovnkk/Xxxx/r/PPP16pVq/TWW29pxowZuvDCC9XQ0NDp89x555269NJLtWnTJp1//vm64oor9OGHH3YY/8knn+i+++7TL37xC7366qtqaGjQTTfdFLr/ox/9SE8//bRqamr0+uuvq7m5WUuXLu10DuvWrdPVV1+t+fPna+PGjZo6dap+8IMfhMVE+/kMw5DT6dRdd90lv98fSswOHDigiRMn6g9/+IPefvttXXPNNbryyiv15ptvdjonAAAAZDkzwzU1NZmSzKampoh7n376qfnOO++Yn376aZef98gR03Q6TVNq/8tmM02Xy4pLlJqaGrOwsDB0/fLLL5uSzKVLl0Z97Iknnmg+9NBDoeuRI0eaP/7xj0PXksxbb701dP3xxx+bksw//vGPYd/ro48+Cs1Fkrlt27bQYx5++GFz2LBhoethw4aZ9957b+j6yJEj5ogRI8yysrIO53n55Zeb559/ftjYZZddFvZzd+fn68gFF1xg3njjjR3e78l7BgAAAKnVWW7QGitBHfB6I1eAWjNNqbHRiku2M844I+z6448/1k033aTx48erqKhI/fv3V11dXdSVoJNPPjn096OPPloFBQXas2dPh/H9+vXTcccdF7p2OByh+KamJu3evVtf+MIXQvftdrsmTpzY6Rzq6uo0adKksLHJkyfH5ecLBAL6/ve/r5NOOkkDBw5U//799eKLL0Z9HAAAALIbhRE60OqoS1zi4unoo48Ou77pppu0YsUK3XfffRozZoz69u2r8vJyHTp0qNPn6d27d9i1zWZTS0tLl+JN0+zi7Luuuz/fvffeq+rqalVVVemkk07S0UcfrcrKyqiPAwAAQGwCLQF5G7zy7/PLMcAh9wi37HkJqiAWRyRBHXA44huXSK+//rrmzJmjiy++WJK1crJjx46kzqGwsFDDhg3T+vXrddZZZ0myVmL+8pe/6NRTT+3wcePHj9e6devCxtauXRt2HcvP16dPHwUCgYjHlZWV6atf/aokqaWlRe+++64+97nPdedHBAAAQCtGnaGK5RV6v/nf26ecBU5Vz6iWZ7wnhTOLju1wHXC7JadT+qzQWASbTXK5rLhUO/7442UYhjZu3Ki//vWvmjVrVqcrOoly3XXXadGiRfrd736nLVu2qKKiQh999FGoWlt7rr/+ei1fvlz33Xeftm7dqp/85Cdavnx5WEwsP9+oUaP06quvyufz6V//+lfocStWrNAbb7yhuro6ffOb39Tu3bvj/4MDAADkGKPOUPmS8rAESJJ8zT6VLymXUZeiCmIxIgnqgN0uVVdbf2/7GT54XVWVuH5BXfHAAw/omGOO0ZQpU3ThhRdq+vTpOv3005M+j5tvvlmXX365rrrqKk2ePFn9+/fX9OnTddRRR3X4mP/4j//Qz3/+c1VXV+uUU07Rn/70J916661hMbH8fHfddZd27Nih4447LtQT6dZbb9Xpp5+u6dOnq7S0VMXFxVHLdQMAAKBzgZaAKpZXyFTksYjgWOXySgVaAhH304XNTMahjgRqbm5WYWGhmpqaVFBQEHbvwIEDqq+v1+jRozv9IN4Zw5AqKsKLJLhcVgLkSe9VvpRraWnR+PHjdemll+r73/9+qqcTk3i8ZwAAALLZ6h2rNfWpqVHjXp79skpHlSZ+Qq10lhu0xpmgKDweqazMqgLn91tngNzu9FgBSjfvvfee/vSnP+nss8/WwYMH9ZOf/ET19fWaNWtWqqcGAACAOPHvi60yWKxxqUASFAO7XSotTfUs0l9eXp4WL16sm266SaZpasKECVq5cqXGjx+f6qkBAAAgThwDYqsMFmtcKpAEIW5cLpdef/31VE8DAAAACeQe4ZazwClfs6/dc0E22eQscMo9Ig0qiHWAwggAAAAAYmbPs6t6hlVBzKbwCmLB66oZVWndL4gkCAAAAECXeMZ7VHtprUoKSsLGnQVO1V5am/Z9gtgOBwAAAOSwQEtA3gav/Pv8cgxwyD3CHdMqjme8R2Vjy7r12FQjCQIAAABylFFnqGJ5RVjTU2eBU9UzqmNazbHn2ZNeBjse2A4HAAAA5CCjzlD5kvKwBEiSfM0+lS8pl1FnpGhmiUcSBAAAAOSYQEtAFcsr2q3uFhyrXF6pQEsg2VNLCpKgHHfHHXfo1FNPTcn3njNnjmbOnJmS7w0AAJDLvA3eiBWg1kyZamxulLfBm8RZJQ9JUJqx2Wydft1xxx09eu6lS5eGjd10001atWpVzyadJDt27JDNZtPGjRtTPRUAAICM5t/nj2tcpul2EvTqq6/qwgsv1PDhw9v9cG2apm677TY5HA717dtX06ZN09atW8NiPvzwQ11xxRUqKChQUVGRrr76an388cfdnVLCBFoCWr1jtZ7927NavWN1QpcF/X5/6KuqqkoFBQVhYzfddFNcv1///v01aNCguD4nAAAA0ptjgCOucZmm20nQ/v37dcopp+jhhx9u9/4999yjBx98UI888ojWrVuno48+WtOnT9eBAwdCMVdccYX+/ve/a8WKFXr++ef16quv6pprrunulBLCqDM0qnqUpj41VbOMWZr61FSNqh6VsINixcXFoa/CwkLZbLawsV/96lcaP368jjrqKI0bN04//elPQ489dOiQ5s+fL4fDoaOOOkojR47UokWLJEmjRo2SJF188cWy2Wyh67bb4YJb1O677z45HA4NGjRI8+bN0+HDh0Mxfr9fF1xwgfr27avRo0frmWee0ahRo1RVVdXhzxUIBLRgwQIVFRVp0KBB+u53vyvTDN+Dunz5cp155pmhmC9/+cvavn176P7o0aMlSaeddppsNptKS0slSevXr9eXvvQlDR48WIWFhTr77LP1l7/8pasvPQAAQM5wj3DLWeCMaHYaZJNNrgKX3CPcSZ5ZcnQ7CTrvvPP0gx/8QBdffHHEPdM0VVVVpVtvvVVlZWU6+eST9X//93/auXNnaMWorq5Oy5cv1+OPP65JkybpzDPP1EMPPaRf/epX2rlzZ7d/oHhKt4oZTz/9tG677Tb98Ic/VF1dnf73f/9X3/ve9/TUU09Jkh588EEtW7ZMS5Ys0ZYtW/T000+Hkp3169dLkmpqauT3+0PX7Xn55Ze1fft2vfzyy3rqqae0ePFiLV68OHT/qquu0s6dO7V69Wr95je/0WOPPaY9e/Z0Ovf7779fixcv1pNPPqnXXntNH374oX7729+Gxezfv18LFizQn//8Z61atUp5eXm6+OKL1dLSIkl68803JUkrV66U3++XYViv/759+zR79my99tprWrt2rY4//nidf/752rdvX+wvLgAAQA6x59lVPaNakiISoeB11YyqjOj50x0J6RNUX1+vXbt2adq0aaGxwsJCTZo0SWvWrNF//dd/ac2aNSoqKtIZZ5wRipk2bZry8vK0bt26dpMrSTp48KAOHjwYum5ubk7EjxC1YoZNNlUur1TZ2LKkvTluv/123X///fJ4rJrto0eP1jvvvKNHH31Us2fPVkNDg44//nideeaZstlsGjlyZOixQ4YMkSQVFRWpuLi40+9zzDHH6Cc/+YnsdrvGjRunCy64QKtWrdLcuXO1efNmrVy5UuvXrw/97h5//HEdf/zxnT5nVVWVFi5cGJr7I488ohdffDEs5pJLLgm7fvLJJzVkyBC98847mjBhQuhnGDRoUNjP8J//+Z9hj3vsscdUVFSkV155RV/+8pc7nRcAAECu8oz3qPbS2nb7BFXNqIqpT1CmSkgStGvXLknSsGHDwsaHDRsWurdr1y4NHTo0fDK9emngwIGhmPYsWrRId955Z5xnHKkrFTOS0SBq//792r59u66++mrNnTs3NH7kyBEVFhZKsrayfelLX9LYsWM1Y8YMffnLX9a5557b5e914oknym7/d2LncDj0t7/9TZK0ZcsW9erVS6effnro/pgxY3TMMcd0+HxNTU3y+/2aNGlSaKxXr14644wzwrbEbd26VbfddpvWrVunf/3rX6EVoIaGBk2YMKHD59+9e7duvfVWrV69Wnv27FEgENAnn3yihoaGLv/sAAAAmSrQEpC3wSv/Pr8cAxxyj3BH/cd6z3iPysaWdflxmS4hSVAiLVy4UAsWLAhdNzc3y+Vyxf37pFvFjGDBiJ///OdhyYSkUMJy+umnq76+Xn/84x+1cuVKXXrppZo2bZpqa2u79L169+4ddm2z2UIJSSJdeOGFGjlypH7+859r+PDhamlp0YQJE3To0KFOHzd79mx98MEHqq6u1siRI5Wfn6/JkydHfRwAAEC2MOqMdld0qmdUR13RsefZk/KP+ukkISWyg1uVdu/eHTa+e/fu0L3i4uKIcyRHjhzRhx9+2Ol2rfz8fBUUFIR9JUK6VcwYNmyYhg8frn/84x8aM2ZM2FewYIAkFRQU6LLLLtPPf/5zPffcc/rNb36jDz/8UJKV3AQCPatsN3bsWB05ckRvvfVWaGzbtm366KOPOnxMYWGhHA6H1q1bFxo7cuSINmzYELr+4IMPtGXLFt16660655xzNH78+Ijn7NOnjyRF/Ayvv/66rr/+ep1//vk68cQTlZ+fr3/96189+jkBAAAyRbqdY88ECUmCRo8ereLi4rD+M83NzVq3bp0mT54sSZo8ebL27t0b9kH4pZdeUktLS8RKRyqkY8WMO++8U4sWLdKDDz6od999V3/7299UU1OjBx54QJL0wAMP6Nlnn9XmzZv17rvv6te//rWKi4tVVFQkyaoQt2rVKu3atavTpKUz48aN07Rp03TNNdfozTff1FtvvaVrrrlGffv2lc3W/mslSRUVFbr77ru1dOlSbd68Wd/+9re1d+/e0P1jjjlGgwYN0mOPPaZt27bppZdeClvxk6ShQ4eqb9++Wr58uXbv3q2mpiZJ0vHHH69f/OIXqqur07p163TFFVeob9++3fr5AAAAMkm0c+ySVLm8MqEtXjJRt5Ogjz/+WBs3bgw1rqyvr9fGjRvV0NAgm82myspK/eAHP9CyZcv0t7/9TVdddZWGDx+umTNnSpLGjx+vGTNmaO7cuXrzzTf1+uuva/78+fqv//ovDR8+PB4/W4+kY8WMb3zjG3r88cdVU1Ojk046SWeffbYWL14cWgkaMGCA7rnnHp1xxhn6/Oc/rx07duiFF15QXp71a77//vu1YsUKuVwunXbaad2ex//93/9p2LBhOuuss3TxxRdr7ty5GjBggI466qgOH3PjjTfqyiuv1OzZszV58mQNGDAgrPhFXl6efvWrX2nDhg2aMGGCbrjhBt17771hz9GrVy89+OCDevTRRzV8+HCVlZVJkp544gl99NFHOv3003XllVfq+uuvjzhvBgAAkI26co4d/2Yz2zZridHq1as1derUiPHZs2dr8eLFMk1Tt99+ux577DHt3btXZ555pn7605/qhBNOCMV++OGHmj9/vn7/+98rLy9Pl1xyiR588EH1798/5nk0NzersLBQTU1NEVvjDhw4oPr6eo0ePbrTD+idaW9/pavAlfUVM7ri/fffl8vl0sqVK3XOOeekejo9Eo/3DAAAQLI8+7dnNcuYFTXuGc8zuvyky5Mwo9TqLDdordtJULpIdBIkda/SRjZ76aWX9PHHH+ukk06S3+/Xd7/7Xfl8Pr377rsRRRUyDUkQAADIJKt3rNbUpyIXJtp6efbLOVH8INYkKOOqw6VCLlbM6Mzhw4f13//93/rHP/6hAQMGaMqUKXr66aczPgECAADINMFz7L5mX7vngmyyyVngTOo59kxAEoQumz59uqZPn57qaQAAAOS84Dn28iXlsskWlgil6hx7JkhIdTgAAAAAyeEZ71HtpbUqKSgJG3cWOFV7aS3n2NvBShAAAACQJrp7Ft0z3qOysWWcY48RSRAAAACQBtqrSuwscKp6RnVMqzmcY48d2+EAAACAFDPqDJUvKY/o+eNr9ql8SbmMOiNFM8tOJEEAAABACgVaAqpYXtFudbfgWOXySgVaAsmeWtYiCQIAAABSyNvgjVgBas2UqcbmRnkbvEmcVXYjCcpxc+bM0cyZM0PXpaWlqqys7NFzxuM5AAAAcoV/nz+ucYiOJChNzZkzRzabTTabTX369NGYMWN011136ciRIwn9voZh6Pvf/35MsatXr5bNZtPevXu7/RwAAAC5zjHAEdc4REd1uFgEApLXK/n9ksMhud2SPfHlBmfMmKGamhodPHhQL7zwgubNm6fevXtr4cKFYXGHDh1Snz594vI9Bw4cmBbPAQAAkCvcI9xyFjjla/a1ey7IJpucBU65R7hTMLvsxEpQNIYhjRolTZ0qzZpl/TlqlDWeYPn5+SouLtbIkSN17bXXatq0aVq2bFloC9sPf/hDDR8+XGPHjpUkNTY26tJLL1VRUZEGDhyosrIy7dixI/R8gUBACxYsUFFRkQYNGqTvfve7Ms3w/6G13cp28OBB3XzzzXK5XMrPz9eYMWP0xBNPaMeOHZo6daok6ZhjjpHNZtOcOXPafY6PPvpIV111lY455hj169dP5513nrZu3Rq6v3jxYhUVFenFF1/U+PHj1b9/f82YMUN+/7+XfFevXq0vfOELOvroo1VUVKQvfvGLeu+99+L0SgMAAKSOPc+u6hnVkqyEp7XgddWMKnr+xBFJUGcMQyovl95vc1DN57PGk5AItda3b18dOnRIkrRq1Spt2bJFK1as0PPPP6/Dhw9r+vTpGjBggLxer15//fVQMhF8zP3336/FixfrySef1GuvvaYPP/xQv/3tbzv9nldddZWeffZZPfjgg6qrq9Ojjz6q/v37y+Vy6Te/+Y0kacuWLfL7/aqurm73OebMmaM///nPWrZsmdasWSPTNHX++efr8OHDoZhPPvlE9913n37xi1/o1VdfVUNDg2666SZJ0pEjRzRz5kydffbZ2rRpk9asWaNrrrlGNput3e8HAACQaTzjPaq9tFYlBSVh484Cp2ovrY2pTxBix3a4jgQCUkWFZEYuSco0JZtNqqyUysoSvjXONE2tWrVKL774oq677jr985//1NFHH63HH388tA3ul7/8pVpaWvT444+HkoOamhoVFRVp9erVOvfcc1VVVaWFCxfK47H+R/TII4/oxRdf7PD7vvvuu1qyZIlWrFihadOmSZKOPfbY0P3gtrehQ4eqqKio3efYunWrli1bptdff11TpkyRJD399NNyuVxaunSpvvKVr0iSDh8+rEceeUTHHXecJGn+/Pm66667JEnNzc1qamrSl7/85dD98ePHd/2FBAAASJJAS0DeBq/8+/xyDHDIPcIddSXHM96jsrFlXX4cuo4kqCNeb+QKUGumKTU2WnGlpQmZwvPPP6/+/fvr8OHDamlp0axZs3THHXdo3rx5Oumkk8LOAf31r3/Vtm3bNGDAgLDnOHDggLZv366mpib5/X5NmjQpdK9Xr14644wzIrbEBW3cuFF2u11nn312t3+Guro69erVK+z7Dho0SGPHjlVdXV1orF+/fqEER5IcDof27NkjyUq25syZo+nTp+tLX/qSpk2bpksvvVQOB4cDAQBA+jHqDFUsrwgre+0scKp6RnXUFR17nl2lo0oTPEOwHa4j/hhLEMYa1w1Tp07Vxo0btXXrVn366ad66qmndPTRR0tS6M+gjz/+WBMnTtTGjRvDvt59913NmjWrW9+/b9++Pf4ZYtW7d++wa5vNFpac1dTUaM2aNZoyZYqee+45nXDCCVq7dm3S5gcAABALo85Q+ZLyiL4/vmafypeUy6hL7nEKtI8kqCOxrjIkcDXi6KOP1pgxYzRixAj16tX5ot3pp5+urVu3aujQoRozZkzYV2FhoQoLC+VwOLRu3brQY44cOaINGzZ0+JwnnXSSWlpa9Morr7R7P7gSFQh03L14/PjxOnLkSNj3/eCDD7RlyxZ97nOf6/Rnauu0007TwoUL9cYbb2jChAl65plnuvR4AACARAq0BFSxvKLdCm/BscrllQq0dPzZCclBEtQRt1tyOq2zP+2x2SSXy4pLA1dccYUGDx6ssrIyeb1e1dfXa/Xq1br++uv1/mfb+ioqKnT33Xdr6dKl2rx5s7797W9H9PhpbdSoUZo9e7a+/vWva+nSpaHnXLJkiSRp5MiRstlsev755/XPf/5TH3/8ccRzHH/88SorK9PcuXP12muv6a9//au++tWv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CQIAIIe43VYVuLbNToNsNsnlsuIAIFuRBAEAkEPsdqsMthSZCAWvq6ro+QMgu5EEAQCQYzweqbZWKikJH3c6rfFY+gQBQCajWSoAABkuELCqufn91lketzv6So7HI5WVdf1xAJANSIIAAMhghmH1/Wld9trptLa8RVvRsdul0tKETg8A0hLb4QAAyFCGIZWXR/b98fmsccNIzbwAIN0lNAlatGiRPv/5z2vAgAEaOnSoZs6cqS1btoTFlJaWymazhX1961vfSuS0AADIeIGAtQJkmpH3gmOVlVYcACBcQpOgV155RfPmzdPatWu1YsUKHT58WOeee672798fFjd37lz5/f7Q1z333JPIaQEAkPG83sgVoNZMU2pstOIAAOESeiZo+fLlYdeLFy/W0KFDtWHDBp111lmh8X79+qm4uDiRUwEAIKv4/fGNA4BcktQzQU1NTZKkgQMHho0//fTTGjx4sCZMmKCFCxfqk08+6fA5Dh48qObm5rAvAAByjcMR3zgAyCVJqw7X0tKiyspKffGLX9SECRNC47NmzdLIkSM1fPhwbdq0STfffLO2bNkio4PTnIsWLdKdd96ZrGkDAJCW3G6rCpzP1/65IJvNuu92J39uAJDubKbZ3n864+/aa6/VH//4R7322mtyOp0dxr300ks655xztG3bNh133HER9w8ePKiDBw+Grpubm+VyudTU1KSCgoKEzB0AgHQUrA4nhSdCNpv1J41PAeSa5uZmFRYWRs0NkrIdbv78+Xr++ef18ssvd5oASdKkSZMkSdu2bWv3fn5+vgoKCsK+AADIRR6PleiUlISPO50kQADQmYRuhzNNU9ddd51++9vfavXq1Ro9enTUx2zcuFGS5GATMwAgxwQCVjU3v986y+N2Ww1NO+PxSGVlXX8cAOSyhCZB8+bN0zPPPKPf/e53GjBggHbt2iVJKiwsVN++fbV9+3Y988wzOv/88zVo0CBt2rRJN9xwg8466yydfPLJiZwaAABpxTCsvj+ty147nVJ1dfQVHbtdKi1N6PQAIKsk9EyQLbgpuY2amhrNmTNHjY2N+upXv6q3335b+/fvl8vl0sUXX6xbb7015m1use77AwAgXQXP9rT9f2TO9gBA18SaGyStMEKikAQBADJZICCNGtVx49Nglbf6era4AUA0aVUYAQAAtM/r7TgBkqzVocZGKw4AEB8kQQAApJDfH984AEB0JEEAAKRQrMVQKZoKAPFDEgQAQAq53daZnw5qCclmk1wuKw4AEB8kQQAApJDdbpXBliIToeB1VRVFEQAgnkiCAABIMY/HKoNdUhI+7nRSHhsAEiGhzVIBAMg1gYBVyc3vt87xuN2xreJ4PFJZWfceCwDoGpIgAADixDCkiorwktdOp7XdLZbVHLtdKi1N2PQAAJ9hOxwAAHFgGFJ5eWTPH5/PGjeM1MwLABCJJAgAgB4KBKwVINOMvBccq6y04gAAqUcSBABAD3m9kStArZmm1NhoxQEAUo8kCACAHvL74xsHAEgskiAAAHrI4YhvHAAgsUiCAADoIbfbqgLXttlpkM0muVxWHAAg9UiCAADoIbvdKoMtRSZCweuqKnr+AEC6IAkCACAOPB6ptlYqKQkfdzqt8Vj6BAEAkoNmqQAAtCMQsKq5+f3WWR63O/pKjscjlZV1/XEAgOQiCQIAoA3DsPr+tC577XRaW96irejY7VJpaUKnBwDoIbbDAQDQimFI5eWRfX98PmvcMFIzLwBA/JAEAQDwmUDAWgEyzch7wbHKSisOAJC5SIIAAPiM1xu5AtSaaUqNjVYcACBzkQQBAPAZvz++cQCA9EQSBADAZxyO+MYBANITSRAAAJ9xu60qcG0bngbZbJLLZcUBADIXSRAAAJ+x260y2FJkIhS8rqqi7w8AZDqSIAAAWvF4pNpaqaQkfNzptMaj9QkCAKQ/mqUCALJaIGBVc/P7rbM8bnf0lRyPRyor6/rjAACZgSQIAJC1DMPq+9O67LXTaW15i7aiY7dLpaUJnR4AIEXYDgcAyEqGIZWXR/b98fmsccNIzbwAAKlHEgQAyDqBgLUCZJqR94JjlZVWHAAg95AEAQCyjtcbuQLUmmlKjY1WHAAg95AEAQCyjt8f3zgAQHYhCQIAZB2HI75xAIDsQhIEAMg6brdVBa5tw9Mgm01yuaw4AEDuIQkCAGQdu90qgy1FJkLB66oq+v4AQK4iCQIAZCWPR6qtlUpKwsedTms8Wp8gAED2olkqACDtBQJWJTe/3zrH43bHtorj8UhlZd17LAAge5EEAQDSmmFYPX9al7x2Oq3tbrGs5tjtUmlpwqYHAMhAbIcDAKQtw5DKyyN7/vh81rhhpGZeAIDMRhIEAEhLgYC1AmSakfeCY5WVVhwAAF1BEgQASEteb+QKUGumKTU2WnEAAHQFSRAAIC35/fGNAwAgiCQIAJCWHI74xgEAEEQSBABIS263VQWubbPTIJtNcrmsOAAAuoIkCACQlux2qwy2FJkIBa+rquj5AwDoOpIgAEDa8nik2lqppCR83Om0xmPpEwQAQFs0SwUAJE0gYFVz8/utszxud/SVHI9HKivr+uMAAOgISRAAICkMw+r707rstdNpbXmLtqJjt0ulpQmdHgAgh7AdDgCQcIYhlZdH9v3x+axxw0jNvAAAuYkkCACQUIGAtQJkmpH3gmOVlVYcAADJQBIEAEgorzdyBag105QaG604AACSgSQIAJBQfn984wAA6Km0SIIefvhhjRo1SkcddZQmTZqkN998M9VTAgDEicMR3zgAAHoq5UnQc889pwULFuj222/XX/7yF51yyimaPn269uzZk+qpAQDiwO22qsC1bXgaZLNJLpcVBwBAMqQ8CXrggQc0d+5cfe1rX9PnPvc5PfLII+rXr5+efPLJVE8NABAHdrtVBluKTISC11VV9P0BACRPSpOgQ4cOacOGDZo2bVpoLC8vT9OmTdOaNWvafczBgwfV3Nwc9gUASG8ej1RbK5WUhI87ndZ4tD5BAADEU0qbpf7rX/9SIBDQsGHDwsaHDRumzZs3t/uYRYsW6c4770zG9AAA7QgErEpufr91jsftjm0Vx+ORysq691gAAOIppUlQdyxcuFALFiwIXTc3N8vlcqVwRgCQOwzD6vnTuuS102ltd4tlNcdul0pLEzY9AABiktIkaPDgwbLb7dq9e3fY+O7du1VcXNzuY/Lz85Wfn5+M6QEAWjEMqbw8sumpz2eNs60NAJApUnomqE+fPpo4caJWrVoVGmtpadGqVas0efLkFM4MANBaIGCtALVNgKR/j1VWWnEAAKS7lFeHW7BggX7+85/rqaeeUl1dna699lrt379fX/va11I9NQDAZ7ze8C1wbZmm1NhoxQEAkO5Sfibosssu0z//+U/ddttt2rVrl0499VQtX748olgCACB1/P74xgEAkEopT4Ikaf78+Zo/f36qpwEA6IDDEd84AABSKeXb4QAA6c/ttqrAtW12GmSzSS6XFQcAQLojCQIARGW3W2WwpchEKHhdVUXPHwBAZiAJAgDExOOxymCXlISPO52UxwYAZJa0OBMEAEi+QMCq5ub3W2d53O7o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dOhQzZw5U1u2bAmLKS0tjXjffutb30rRjDPTHXfcEfEajhs3LnT/wIEDmjdvngYNGqT+/fvrkksu0e7du1M448zU3v/f2Ww2zZs3TxLv5e549dVXdeGFF2r48OGy2WxaunRp2H3TNHXbbbfJ4XCob9++mjZtmrZu3RoW8+GHH+qKK65QQUGBioqKdPXVV+vjjz+O6zxJgrrp0KFD+spXvqJrr7223fuBQEAXXHCBDh06pDfeeENPPfWUFi9erNtuuy0UU19frwsuuEBTp07Vxo0bVVlZqW984xt68cUXk/VjZJQpU6bI7/eHfX3jG9/Q6NGjdcYZZ4TFrly5Mixu4sSJKZp15rrrrrvCXsPrrrsudK+5uVnnnnuuRo4cqQ0bNujee+/VHXfcocceeyyFM84smzdvVktLix599FH9/e9/149//GM98sgj+u///u+IWN7P3ffcc89pwYIFuv322/WXv/xFp5xyiqZPn649e/akemoZ65VXXtG8efO0du1arVixQocPH9a5556r/fv3h8XNnTs37H3LP5R03Yknnhj2Gr722muhezfccIN+//vf69e//rVeeeUV7dy5Ux6PJ4WzzUzr168Pe41XrFghSfrKV74SiuG93DX79+/XKaecoocffrjd+/fcc48efPBBPfLII1q3bp2OPvpoTZ8+XQcOHAjFXHHFFfr73/+uFStW6Pnnn9err76qa665Jr4TNdEjNTU1ZmFhYcT4Cy+8YObl5Zm7du0Kjf3sZz8zCwoKzIMHD5qmaZrf/e53zRNPPDHscZdddpk5ffr0hM45Wxw6dMgcMmSIedddd4XG6uvrTUnmW2+9lbqJZYGRI0eaP/7xjzu8/9Of/tQ85phjQu9l0zTNm2++2Rw7dmwSZpe97rnnHnP06NGha97PPfeFL3zBnDdvXug6EAiYw4cPNxctWpTCWWWXPXv2mJLMV155JTR29tlnmxUVFambVBa4/fbbzVNOOaXde3v37jV79+5t/vrXvw6N1dXVmZLMNWvWJGmG2amiosI87rjjzJaWFtM0eS/3lCTzt7/9bei6paXFLC4uNu+9997Q2N69e838/Hzz2WefNU3TNN955x1Tkrl+/fpQzB//+EfTZrOZPp8vbnNjJShB1qxZo5NOOknDhg0LjU2fPl3Nzc36+9//HoqZNm1a2OOmT5+uNWvWJHWumWrZsmX64IMP9LWvfS3i3kUXXaShQ4fqzDPP1LJly1Iwu8x39913a9CgQTrttNN07733hm3lXLNmjc466yz16dMnNDZ9+nRt2bJFH330USqmmxWampo0cODAiHHez91z6NAhbdiwIey/s3l5eZo2bRr/nY2jpqYmSYp47z799NMaPHiwJkyYoIULF+qTTz5JxfQy2tatWzV8+HAde+yxuuKKK9TQ0CBJ2rBhgw4fPhz23h43bpxGjBjBe7sHDh06pF/+8pf6+te/LpvNFhrnvRw/9fX12rVrV9h7t7CwUJMmTQq9d9esWaOioqKwXT7Tpk1TXl6e1q1bF7e59IrbMyHMrl27whIgSaHrXbt2dRrT3NysTz/9VH379k3OZDPUE088oenTp8vpdIbG+vfvr/vvv19f/OIXlZeXp9/85jeaOXOmli5dqosuuiiFs80s119/vU4//XQNHDhQb7zxhhYuXCi/368HHnhAkvXeHT16dNhjWr+/jznmmKTPOdNt27ZNDz30kO67777QGO/nnvnXv/6lQCDQ7n9nN2/enKJZZZeWlhZVVlbqi1/8oiZMmBAanzVrlkaOHKnhw4dr06ZNuvnmm7VlyxYZhpHC2WaWSZMmafHixRo7dqz8fr/uvPNOud1uvf3229q1a5f69OkTcSZ52LBhoc8Y6LqlS5dq7969mjNnTmiM93J8Bd+f7f13ufXn46FDh4bd79WrlwYOHBjX9zdJUCu33HKLfvSjH3UaU1dXF3YwET3Xndf9/fff14svvqglS5aExQ0ePFgLFiwIXX/+85/Xzp07de+99+b8h8auvM6tX8OTTz5Zffr00Te/+U0tWrRI+fn5iZ5qRuvO+9nn82nGjBn6yle+orlz54bGeT8j3c2bN09vv/122FkVSWF790866SQ5HA6dc8452r59u4477rhkTzMjnXfeeaG/n3zyyZo0aZJGjhypJUuW8I+kCfLEE0/ovPPO0/Dhw0NjvJezF0lQKzfeeGNY9t+eY489NqbnKi4ujqhAFKzaUlxcHPqzbSWX3bt3q6CgIKf+A9ed172mpkaDBg2K6YPgpEmTQgcdc1lP3t+TJk3SkSNHtGPHDo0dO7bD96707/d3rurq67xz505NnTpVU6ZMiamwBO/n2A0ePFh2u73d92quv0/jYf78+aEDy61X5NszadIkSdaKJx8cu6eoqEgnnHCCtm3bpi996Us6dOiQ9u7dG7YaxHu7+9577z2tXLky6goP7+WeCb4/d+/eLYfDERrfvXu3Tj311FBM2+I1R44c0YcffhjX9zdJUCtDhgzRkCFD4vJckydP1g9/+EPt2bMntKS3YsUKFRQU6HOf+1wo5oUXXgh73IoVKzR58uS4zCFTdPV1N01TNTU1uuqqq9S7d++o8Rs3bgz7H1qu6sn7e+PGjcrLywu9lydPnqz/+Z//0eHDh0O/gxUrVmjs2LE5vxWuK6+zz+fT1KlTNXHiRNXU1CgvL/oxTd7PsevTp48mTpyoVatWaebMmZKs7VurVq3S/PnzUzu5DGaapq677jr99re/1erVqyO2xrZn48aNksR7twc+/vhjbd++XVdeeaUmTpyo3r17a9WqVbrkkkskSVu2bFFDQ0POfYaIl5qaGg0dOlQXXHBBp3G8l3tm9OjRKi4u1qpVq0JJT3Nzs9atWxequDx58mTt3btXGzZsCFVDfemll9TS0hJKQuMibiUWcsx7771nvvXWW+add95p9u/f33zrrbfMt956y9y3b59pmqZ55MgRc8KECea5555rbty40Vy+fLk5ZMgQc+HChaHn+Mc//mH269fP/M53vmPW1dWZDz/8sGm3283ly5en6sfKCCtXrjQlmXV1dRH3Fi9ebD7zzDNmXV2dWVdXZ/7whz808/LyzCeffDIFM81Mb7zxhvnjH//Y3Lhxo7l9+3bzl7/8pTlkyBDzqquuCsXs3bvXHDZsmHnllVeab7/9tvmrX/3K7Nevn/noo4+mcOaZ5f333zfHjBljnnPOOeb7779v+v3+0FcQ7+ee+9WvfmXm5+ebixcvNt955x3zmmuuMYuKisIqd6Jrrr32WrOwsNBcvXp12Pv2k08+MU3TNLdt22bedddd5p///Gezvr7e/N3vfmcee+yx5llnnZXimWeWG2+80Vy9erVZX19vvv766+a0adPMwYMHm3v27DFN0zS/9a1vmSNGjDBfeukl889//rM5efJkc/LkySmedWYKBALmiBEjzJtvvjlsnPdy9+zbty/0uViS+cADD5hvvfWW+d5775mmaZp33323WVRUZP7ud78zN23aZJaVlZmjR482P/3009BzzJgxwzzttNPMdevWma+99pp5/PHHm5dffnlc50kS1E2zZ882JUV8vfzyy6GYHTt2mOedd57Zt29fc/DgweaNN95oHj58OOx5Xn75ZfPUU081+/TpYx577LFmTU1Ncn+QDHT55ZebU6ZMaffe4sWLzfHjx5v9+vUzCwoKzC984QthJUQR3YYNG8xJkyaZhYWF5lFHHWWOHz/e/N///V/zwIEDYXF//etfzTPPPNPMz883S0pKzLvvvjtFM85MNTU17f43pPW/TfF+jo+HHnrIHDFihNmnTx/zC1/4grl27dpUTymjdfS+Df7/V0NDg3nWWWeZAwcONPPz880xY8aY3/nOd8ympqbUTjzDXHbZZabD4TD79OljlpSUmJdddpm5bdu20P1PP/3U/Pa3v20ec8wxZr9+/cyLL7447B9RELsXX3zRlGRu2bIlbJz3cve8/PLL7f43Yvbs2aZpWmWyv/e975nDhg0z8/PzzXPOOSfitf/ggw/Myy+/3Ozfv79ZUFBgfu1rXwstNMSLzTRNM37rSgAAAACQ3ugTBAAAACCnkAQBAAAAyCkkQQAAAAByCkkQAAAAgJxCEgQAAAAgp5AEAQAAAMgpJEEAAAAAcgpJEAAAAICcQhIEAAAAIKeQBAEAAADIKSRBAAAAAHLK/wP2vUiGWaaEhwAAAABJRU5ErkJggg==\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "H63NPcgPcwZV"
      },
      "source": [
        "From the plot we can see our predictions aren't totally outlandish but they definitely aren't anything special either."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "orAfIWOrgRDA"
      },
      "source": [
        "## Evaluating predictions\n",
        "\n",
        "Alongisde visualizations, evaulation metrics are your alternative best option for evaluating your model.\n",
        "\n",
        "Depending on the problem you're working on, different models have different evaluation metrics. \n",
        "\n",
        "Two of the main metrics used for regression problems are:\n",
        "* **Mean absolute error (MAE)** - the mean difference between each of the predictions.\n",
        "* **Mean squared error (MSE)** - the squared mean difference between of the predictions (use if larger errors are more detrimental than smaller errors).\n",
        "\n",
        "The lower each of these values, the better.\n",
        "\n",
        "You can also use [`model.evaluate()`](https://www.tensorflow.org/api_docs/python/tf/keras/Model#evaluate) which will return the loss of the model as well as any metrics setup during the compile step."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DPgTdF3ddxiY",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b2ee36f3-1f3d-48dd-a4a9-40666798e614"
      },
      "source": [
        "# Evaluate the model on the test set\n",
        "model.evaluate(X_test, y_test)"
      ],
      "execution_count": 32,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 132ms/step - loss: 30.4843 - mae: 30.4843\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[30.484329223632812, 30.484329223632812]"
            ]
          },
          "metadata": {},
          "execution_count": 32
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DAXIRyVzegFd"
      },
      "source": [
        "In our case, since we used MAE for the loss function as well as MAE for the metrics, `model.evaulate()` returns them both.\n",
        "\n",
        "TensorFlow also has built in functions for MSE and MAE.\n",
        "\n",
        "For many evaluation functions, the premise is the same: compare predictions to the ground truth labels."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gqoMQ0dJeD2S",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "2c170104-793b-43c9-dfd3-31bc8264e2e4"
      },
      "source": [
        "# Calculate the mean absolute error\n",
        "mae = tf.metrics.mean_absolute_error(y_true=y_test, \n",
        "                                     y_pred=y_preds)\n",
        "mae"
      ],
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tf.Tensor: shape=(10,), dtype=float32, numpy=\n",
              "array([43.455303, 40.572865, 37.690426, 34.807987, 31.925549, 29.04311 ,\n",
              "       26.160675, 23.278236, 20.39579 , 17.610687], dtype=float32)>"
            ]
          },
          "metadata": {},
          "execution_count": 33
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7pYp3XNYfkyC"
      },
      "source": [
        "Huh? That's strange, MAE should be a single output.\n",
        "\n",
        "Instead, we get 10 values.\n",
        "\n",
        "This is because our `y_test` and `y_preds` tensors are different shapes."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zeUHwOc2gIV4",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "48a311bd-b9eb-4caf-ff7f-a1a28b44abc8"
      },
      "source": [
        "# Check the test label tensor values\n",
        "y_test"
      ],
      "execution_count": 34,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([ 70,  74,  78,  82,  86,  90,  94,  98, 102, 106])"
            ]
          },
          "metadata": {},
          "execution_count": 34
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3aJwlTxugPyc",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d329ceba-d669-4808-c6eb-3dc7388f8cfe"
      },
      "source": [
        "# Check the predictions tensor values (notice the extra square brackets)\n",
        "y_preds"
      ],
      "execution_count": 35,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[44.544697],\n",
              "       [47.427135],\n",
              "       [50.309574],\n",
              "       [53.192013],\n",
              "       [56.07445 ],\n",
              "       [58.95689 ],\n",
              "       [61.839325],\n",
              "       [64.72176 ],\n",
              "       [67.60421 ],\n",
              "       [70.48664 ]], dtype=float32)"
            ]
          },
          "metadata": {},
          "execution_count": 35
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xolZ-lmge_ES",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "39274fda-255e-4b41-c9ce-fb70faf31cb9"
      },
      "source": [
        "# Check the tensor shapes\n",
        "y_test.shape, y_preds.shape"
      ],
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "((10,), (10, 1))"
            ]
          },
          "metadata": {},
          "execution_count": 36
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eW1qleu5gHyZ"
      },
      "source": [
        "Remember how we discussed dealing with different input and output shapes is one the most common issues you'll come across, this is one of those times.\n",
        "\n",
        "But not to worry.\n",
        "\n",
        "We can fix it using [`squeeze()`](https://www.tensorflow.org/api_docs/python/tf/squeeze), it'll remove the the `1` dimension from our `y_preds` tensor, making it the same shape as `y_test`.\n",
        "\n",
        "> 🔑 **Note:** If you're comparing two tensors, it's important to make sure they're the right shape(s) (you won't always have to manipulate the shapes, but always be on the look out, *many* errors are the result of mismatched tensors, especially mismatched input and output shapes)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "tVtMyw70g4aF",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "c542f5ec-1a13-4073-b1a5-e536bd22a4ff"
      },
      "source": [
        "# Shape before squeeze()\n",
        "y_preds.shape"
      ],
      "execution_count": 37,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(10, 1)"
            ]
          },
          "metadata": {},
          "execution_count": 37
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qnYaBnCng-Nq",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a2046fd7-6f44-4bae-a8b0-1e8a0d2151f2"
      },
      "source": [
        "# Shape after squeeze()\n",
        "y_preds.squeeze().shape"
      ],
      "execution_count": 38,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(10,)"
            ]
          },
          "metadata": {},
          "execution_count": 38
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HxvVeD64hEX8",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "e8be73f4-109b-4273-cd2b-12f4b35f2aaa"
      },
      "source": [
        "# What do they look like?\n",
        "y_test, y_preds.squeeze()"
      ],
      "execution_count": 39,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(array([ 70,  74,  78,  82,  86,  90,  94,  98, 102, 106]),\n",
              " array([44.544697, 47.427135, 50.309574, 53.192013, 56.07445 , 58.95689 ,\n",
              "        61.839325, 64.72176 , 67.60421 , 70.48664 ], dtype=float32))"
            ]
          },
          "metadata": {},
          "execution_count": 39
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mfUCIeHyhLk7"
      },
      "source": [
        "Okay, now we know how to make our `y_test` and `y_preds` tenors the same shape, let's use our evaluation metrics."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TvjY6GIJvXBO",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d7d9bb98-3585-4295-f85d-1c25e9b3e640"
      },
      "source": [
        "# Calcuate the MAE\n",
        "mae = tf.metrics.mean_absolute_error(y_true=y_test, \n",
        "                                     y_pred=y_preds.squeeze()) # use squeeze() to make same shape\n",
        "mae"
      ],
      "execution_count": 40,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tf.Tensor: shape=(), dtype=float32, numpy=30.48433>"
            ]
          },
          "metadata": {},
          "execution_count": 40
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EwA9nGJzvbMT",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "401bfaea-7ee3-4fed-e556-a7c17aa371a7"
      },
      "source": [
        "# Calculate the MSE\n",
        "mse = tf.metrics.mean_squared_error(y_true=y_test,\n",
        "                                    y_pred=y_preds.squeeze())\n",
        "mse"
      ],
      "execution_count": 41,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tf.Tensor: shape=(), dtype=float32, numpy=939.59827>"
            ]
          },
          "metadata": {},
          "execution_count": 41
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "X06oo_CIjPbL"
      },
      "source": [
        "We can also calculate the MAE using pure TensorFlow functions."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YxiD6-QBYSzd",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "40eecb0e-aa23-4c52-ae02-794cc9fd48ce"
      },
      "source": [
        "# Returns the same as tf.metrics.mean_absolute_error()\n",
        "tf.reduce_mean(tf.abs(y_test-y_preds.squeeze()))"
      ],
      "execution_count": 42,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<tf.Tensor: shape=(), dtype=float64, numpy=30.484329986572266>"
            ]
          },
          "metadata": {},
          "execution_count": 42
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rmEho4lYofOa"
      },
      "source": [
        "Again, it's a good idea to functionize anything you think you might use over again (or find yourself using over and over again).\n",
        "\n",
        "Let's make functions for our evaluation metrics."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bs1Z2jgNol5f"
      },
      "source": [
        "def mae(y_test, y_pred):\n",
        "  \"\"\"\n",
        "  Calculuates mean absolute error between y_test and y_preds.\n",
        "  \"\"\"\n",
        "  return tf.metrics.mean_absolute_error(y_test,\n",
        "                                        y_pred)\n",
        "  \n",
        "def mse(y_test, y_pred):\n",
        "  \"\"\"\n",
        "  Calculates mean squared error between y_test and y_preds.\n",
        "  \"\"\"\n",
        "  return tf.metrics.mean_squared_error(y_test,\n",
        "                                       y_pred)"
      ],
      "execution_count": 43,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zub5zK7bcl40"
      },
      "source": [
        "## Running experiments to improve a model\n",
        "\n",
        "After seeing the evaluation metrics and the predictions your model makes, it's likely you'll want to improve it.\n",
        "\n",
        "Again, there are many different ways you can do this, but 3 of the main ones are:\n",
        "1. **Get more data** - get more examples for your model to train on (more opportunities to learn patterns).\n",
        "2. **Make your model larger (use a more complex model)** - this might come in the form of more layers or more hidden units in each layer.\n",
        "3. **Train for longer** - give your model more of a chance to find the patterns in the data.\n",
        "\n",
        "Since we created our dataset, we could easily make more data but this isn't always the case when you're working with real-world datasets.\n",
        "\n",
        "So let's take a look at how we can improve our model using 2 and 3.\n",
        "\n",
        "To do so, we'll build 3 models and compare their results:\n",
        "1. `model_1` - same as original model, 1 layer, trained for 100 epochs.\n",
        "2. `model_2` - 2 layers, trained for 100 epochs.\n",
        "3. `model_3` - 2 layers, trained for 500 epochs.\n",
        "\n",
        "**Build `model_1`**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "StVHIIM9csyS",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "4428341a-7418-4fb8-e6d9-2b312a2a8a24"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Replicate original model\n",
        "model_1 = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "model_1.compile(loss=tf.keras.losses.mae,\n",
        "                optimizer=tf.keras.optimizers.SGD(),\n",
        "                metrics=['mae'])\n",
        "\n",
        "# Fit the model\n",
        "model_1.fit(tf.expand_dims(X_train, axis=-1), y_train, epochs=100)"
      ],
      "execution_count": 44,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/100\n",
            "2/2 [==============================] - 0s 19ms/step - loss: 30.0988 - mae: 30.0988\n",
            "Epoch 2/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 8.4388 - mae: 8.4388\n",
            "Epoch 3/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 10.5960 - mae: 10.5960\n",
            "Epoch 4/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 13.1312 - mae: 13.1312\n",
            "Epoch 5/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 12.1970 - mae: 12.1970\n",
            "Epoch 6/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 9.4357 - mae: 9.4357\n",
            "Epoch 7/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.5754 - mae: 8.5754\n",
            "Epoch 8/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.0484 - mae: 9.0484\n",
            "Epoch 9/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 18.7568 - mae: 18.7568\n",
            "Epoch 10/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.1199 - mae: 10.1199\n",
            "Epoch 11/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.4027 - mae: 8.4027\n",
            "Epoch 12/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 10.6692 - mae: 10.6692\n",
            "Epoch 13/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.8023 - mae: 9.8023\n",
            "Epoch 14/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 16.0152 - mae: 16.0152\n",
            "Epoch 15/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 11.4080 - mae: 11.4080\n",
            "Epoch 16/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.5437 - mae: 8.5437\n",
            "Epoch 17/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 13.6405 - mae: 13.6405\n",
            "Epoch 18/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 11.4690 - mae: 11.4690\n",
            "Epoch 19/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 17.9154 - mae: 17.9154\n",
            "Epoch 20/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 15.0500 - mae: 15.0500\n",
            "Epoch 21/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 11.0231 - mae: 11.0231\n",
            "Epoch 22/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.1580 - mae: 8.1580\n",
            "Epoch 23/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.5191 - mae: 9.5191\n",
            "Epoch 24/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 7.6655 - mae: 7.6655\n",
            "Epoch 25/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 13.1908 - mae: 13.1908\n",
            "Epoch 26/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 16.4217 - mae: 16.4217\n",
            "Epoch 27/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 13.1672 - mae: 13.1672\n",
            "Epoch 28/100\n",
            "2/2 [==============================] - 0s 13ms/step - loss: 14.2568 - mae: 14.2568\n",
            "Epoch 29/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.0703 - mae: 10.0703\n",
            "Epoch 30/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 16.3398 - mae: 16.3398\n",
            "Epoch 31/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 23.6485 - mae: 23.6485\n",
            "Epoch 32/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 7.6261 - mae: 7.6261\n",
            "Epoch 33/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 9.3267 - mae: 9.3267\n",
            "Epoch 34/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 13.7369 - mae: 13.7369\n",
            "Epoch 35/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 11.1301 - mae: 11.1301\n",
            "Epoch 36/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 13.3224 - mae: 13.3224\n",
            "Epoch 37/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.4813 - mae: 9.4813\n",
            "Epoch 38/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.1438 - mae: 10.1438\n",
            "Epoch 39/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.1818 - mae: 10.1818\n",
            "Epoch 40/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.9152 - mae: 10.9152\n",
            "Epoch 41/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.9088 - mae: 7.9088\n",
            "Epoch 42/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.0967 - mae: 10.0967\n",
            "Epoch 43/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.7052 - mae: 8.7052\n",
            "Epoch 44/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 12.2103 - mae: 12.2103\n",
            "Epoch 45/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 13.7978 - mae: 13.7978\n",
            "Epoch 46/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.4711 - mae: 8.4711\n",
            "Epoch 47/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.1381 - mae: 9.1381\n",
            "Epoch 48/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.6247 - mae: 10.6247\n",
            "Epoch 49/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.7550 - mae: 7.7550\n",
            "Epoch 50/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 9.5461 - mae: 9.5461\n",
            "Epoch 51/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.1627 - mae: 9.1627\n",
            "Epoch 52/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 16.3674 - mae: 16.3674\n",
            "Epoch 53/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 14.1315 - mae: 14.1315\n",
            "Epoch 54/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 21.1233 - mae: 21.1233\n",
            "Epoch 55/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 16.4010 - mae: 16.4010\n",
            "Epoch 56/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 9.9366 - mae: 9.9366\n",
            "Epoch 57/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.6189 - mae: 9.6189\n",
            "Epoch 58/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 8.9519 - mae: 8.9519\n",
            "Epoch 59/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.1374 - mae: 10.1374\n",
            "Epoch 60/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 8.4572 - mae: 8.4572\n",
            "Epoch 61/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 9.3126 - mae: 9.3126\n",
            "Epoch 62/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.0772 - mae: 7.0772\n",
            "Epoch 63/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.6268 - mae: 8.6268\n",
            "Epoch 64/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.2062 - mae: 9.2062\n",
            "Epoch 65/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.4393 - mae: 10.4393\n",
            "Epoch 66/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 15.7070 - mae: 15.7070\n",
            "Epoch 67/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.0863 - mae: 10.0863\n",
            "Epoch 68/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.0451 - mae: 9.0451\n",
            "Epoch 69/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 12.5786 - mae: 12.5786\n",
            "Epoch 70/100\n",
            "2/2 [==============================] - 0s 9ms/step - loss: 8.9553 - mae: 8.9553\n",
            "Epoch 71/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.9295 - mae: 9.9295\n",
            "Epoch 72/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 9.9702 - mae: 9.9702\n",
            "Epoch 73/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 12.4305 - mae: 12.4305\n",
            "Epoch 74/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.5927 - mae: 10.5927\n",
            "Epoch 75/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.6281 - mae: 9.6281\n",
            "Epoch 76/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 11.0915 - mae: 11.0915\n",
            "Epoch 77/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.2769 - mae: 8.2769\n",
            "Epoch 78/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 8.9623 - mae: 8.9623\n",
            "Epoch 79/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 19.8117 - mae: 19.8117\n",
            "Epoch 80/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 17.8036 - mae: 17.8036\n",
            "Epoch 81/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.0915 - mae: 7.0915\n",
            "Epoch 82/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 10.4045 - mae: 10.4045\n",
            "Epoch 83/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.8260 - mae: 9.8260\n",
            "Epoch 84/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.9471 - mae: 7.9471\n",
            "Epoch 85/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.4590 - mae: 9.4590\n",
            "Epoch 86/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.5023 - mae: 9.5023\n",
            "Epoch 87/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 11.4498 - mae: 11.4498\n",
            "Epoch 88/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.9486 - mae: 9.9486\n",
            "Epoch 89/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.2579 - mae: 7.2579\n",
            "Epoch 90/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 12.7103 - mae: 12.7103\n",
            "Epoch 91/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 7.3206 - mae: 7.3206\n",
            "Epoch 92/100\n",
            "2/2 [==============================] - 0s 12ms/step - loss: 7.6849 - mae: 7.6849\n",
            "Epoch 93/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 7.1229 - mae: 7.1229\n",
            "Epoch 94/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 12.5571 - mae: 12.5571\n",
            "Epoch 95/100\n",
            "2/2 [==============================] - 0s 6ms/step - loss: 9.9330 - mae: 9.9330\n",
            "Epoch 96/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.1413 - mae: 9.1413\n",
            "Epoch 97/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 12.0806 - mae: 12.0806\n",
            "Epoch 98/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 9.0788 - mae: 9.0788\n",
            "Epoch 99/100\n",
            "2/2 [==============================] - 0s 8ms/step - loss: 8.4999 - mae: 8.4999\n",
            "Epoch 100/100\n",
            "2/2 [==============================] - 0s 7ms/step - loss: 14.4517 - mae: 14.4517\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f0065a91180>"
            ]
          },
          "metadata": {},
          "execution_count": 44
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "A-Da56xspOrY",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 617
        },
        "outputId": "c468a93c-d7ed-4274-8ad7-a3c7c62e9efc"
      },
      "source": [
        "# Make and plot predictions for model_1\n",
        "y_preds_1 = model_1.predict(X_test)\n",
        "plot_predictions(predictions=y_preds_1)"
      ],
      "execution_count": 45,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 45ms/step\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1000x700 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAJGCAYAAACdj47VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABjz0lEQVR4nO3de3yT5f3/8XcaoILQVo4NTTgICkw84sYXZrR8ZYI6LcZOJ05hc7g5UCq6Kd+f8zi/OE9rdW7q1OJ3Uyfr7jHmHA4QNCoiYzLmLAis2BoCbCotqJzS+/fHbbKmaZu0zTmv5+ORB97XfSW9GjOXN9d1fS6baZqmAAAAACBH5KV6AAAAAACQTIQgAAAAADmFEAQAAAAgpxCCAAAAAOQUQhAAAACAnEIIAgAAAJBTCEEAAAAAckqPVA+gu5qbm7Vz507169dPNpst1cMBAAAAkCKmaWrfvn0aOnSo8vLan+/J+BC0c+dOuVyuVA8DAAAAQJpoaGiQ0+ls937Gh6B+/fpJsn7RgoKCFI8GAAAAQKo0NTXJ5XKFMkJ7Mj4EBZfAFRQUEIIAAAAARN0mQ2EEAAAAADmFEAQAAAAgpxCCAAAAAOSUjN8TFKtAIKDDhw+nehhIYz179pTdbk/1MAAAAJBgWR+CTNPUrl27tHfv3lQPBRmgqKhIxcXFnDkFAACQxbI+BAUD0ODBg9WnTx++3KJNpmnq008/1Z49eyRJDocjxSMCAABAomR1CAoEAqEANGDAgFQPB2mud+/ekqQ9e/Zo8ODBLI0DAADIUlldGCG4B6hPnz4pHgkyRfCzwv4xAACA7JXVISiIJXCIFZ8VAACA7JcTIQgAAAAAgghBOWLEiBGqrKyMuf+aNWtks9lSUlVv8eLFKioqSvrPBQAAQG4gBKUZm83W4eP222/v0uuuX79eV199dcz9J0+eLL/fr8LCwi79vGTrbMgDAABA7srq6nDxEghIXq/k90sOh+R2S4kqHOb3+0P//Pzzz+vWW2/Vli1bQm19+/YN/bNpmgoEAurRI/q/xkGDBnVqHL169VJxcXGnngMAAABkAmaCojAMacQIacoUaeZM688RI6z2RCguLg49CgsLZbPZQtebN29Wv3799Kc//UkTJkxQfn6+XnvtNW3fvl1lZWUaMmSI+vbtqy9+8YtauXJl2Ou2nimx2Wx64okndNFFF6lPnz467rjjtGzZstD91svhgkvUXnrpJY0bN059+/bV9OnTw0LbkSNHdN1116moqEgDBgzQTTfdpFmzZmnGjBkd/s6LFy/WsGHD1KdPH1100UX68MMPw+5H+/1KS0v1/vvv6/rrrw/NmEnShx9+qMsuu0wlJSXq06ePTjzxRD333HOd+dcBAACALEQI6oBhSOXl0gcfhLf7fFZ7ooJQNDfffLPuuece1dbW6qSTTtL+/ft13nnnadWqVXr77bc1ffp0XXDBBaqvr+/wde644w5dcskl2rRpk8477zxdfvnl+uijj9rt/+mnn+r+++/XL3/5S7366quqr6/XjTfeGLr/4x//WM8884yqq6v1+uuvq6mpSUuXLu1wDOvWrdNVV12lefPmaePGjZoyZYp+9KMfhfWJ9vsZhiGn06k777xTfr8/FMwOHDigCRMm6I9//KPeeecdXX311briiiv01ltvdTgmAAAAZDkzwzU2NpqSzMbGxoh7n332mfnuu++an332Wadf98gR03Q6TVNq+2GzmabLZfVLlOrqarOwsDB0vXr1alOSuXTp0qjPPeGEE8yHH344dD18+HDzJz/5SehaknnLLbeErvfv329KMv/0pz+F/ayPP/44NBZJ5rZt20LPeeSRR8whQ4aErocMGWLed999oesjR46Yw4YNM8vKytod52WXXWaed955YW2XXnpp2O/dld+vPeeff755ww03tHu/O58ZAAAApFZH2aAlZoLa4fVGzgC1ZJpSQ4PVL9lOP/30sOv9+/frxhtv1Lhx41RUVKS+ffuqtrY26kzQSSedFPrno48+WgUFBdqzZ0+7/fv06aNRo0aFrh0OR6h/Y2Ojdu/erS996Uuh+3a7XRMmTOhwDLW1tZo4cWJY26RJk+Ly+wUCAd1111068cQT1b9/f/Xt21cvvfRS1OcBAAAgu1EYoR0ttrrEpV88HX300WHXN954o1asWKH7779fo0ePVu/evVVeXq5Dhw51+Do9e/YMu7bZbGpubu5Uf9M0Ozn6zuvq73ffffepqqpKlZWVOvHEE3X00UeroqIi6vMAAAAQm0BzQN56r/z7/HL0c8g9zC17XoIqiMURIagdDkd8+yXS66+/rtmzZ+uiiy6SZM2c7NixI6ljKCws1JAhQ7R+/XqdeeaZkqyZmL/+9a865ZRT2n3euHHjtG7durC2N998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1cMAAADIecF97OVLymWTLSwIpWofeyZISHU4AAAAAMnhGedRzSU1KikoCWt3FjhVc0kN+9jbwEwQAAAAkCa6uhfdM86jsjFl7GOPESEIAAAASANtVSV2FjhVNb0qptkc9rHHjuVwAAAAQIoZtYbKl5RHnPnja/KpfEm5jFojRSPLToQgAAAAIIUCzQHNXz6/zepuwbaK5RUKNAeSPbSsRQgCAAAAUshb742YAWrJlKmGpgZ5671JHFV2IwTluNmzZ2vGjBmh69LSUlVUVHTrNePxGgAAALnCv88f136IjhCUpmbPni2bzSabzaZevXpp9OjRuvPOO3XkyJGE/lzDMHTXXXfF1HfNmjWy2Wzau3dvl18DAAAg1zn6OeLaD9FRHS4WgYDk9Up+v+RwSG63ZE98ucHp06erurpaBw8e1Isvvqi5c+eqZ8+eWrhwYVi/Q4cOqVevXnH5mf3790+L1wAAAMgV7mFuOQuc8jX52twXZJNNzgKn3MPcKRhddmImKBrDkEaMkKZMkWbOtP4cMcJqT7D8/HwVFxdr+PDhuuaaazR16lQtW7YstITt7rvv1tChQzVmzBhJUkNDgy655BIVFRWpf//+Kisr044dO0KvFwgEtGDBAhUVFWnAgAH6wQ9+INMM/x9a66VsBw8e1E033SSXy6X8/HyNHj1aTz75pHbs2KEpU6ZIko455hjZbDbNnj27zdf4+OOPdeWVV+qYY45Rnz59dO6552rr1q2h+4sXL1ZRUZFeeukljRs3Tn379tX06dPl9/9nynfNmjX60pe+pKOPPlpFRUX68pe/rPfffz9O7zQAAEDq2PPsqppeJckKPC0FryunV3LmTxwRgjpiGFJ5ufRBq41qPp/VnoQg1FLv3r116NAhSdKqVau0ZcsWrVixQi+88IIOHz6sadOmqV+/fvJ6vXr99ddDYSL4nAceeECLFy/WU089pddee00fffSRfve733X4M6+88ko999xzeuihh1RbW6vHHntMffv2lcvl0m9/+1tJ0pYtW+T3+1VVVdXma8yePVt/+ctftGzZMq1du1amaeq8887T4cOHQ30+/fRT3X///frlL3+pV199VfX19brxxhslSUeOHNGMGTN01llnadOmTVq7dq2uvvpq2Wy2Nn8eAABApvGM86jmkhqVFJSEtTsLnKq5pCamc4IQO5bDtScQkObP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RowYoaOOOkoTJ07UW2+9leohZbRFixbpi1/8ovr166fBgwdrxowZ2rJlS1if0tLSiM/td7/73RSNODPdfvvtEe/h2LFjQ/cPHDiguXPnasCAAerbt68uvvhi7d69O4Ujzkxt/f+dzWbT3LlzJfFZ7opXX31VF1xwgYYOHSqbzaalS5eG3TdNU7feeqscDod69+6tqVOnauvWrWF9PvroI11++eUqKChQUVGRrrrqKu3fvz+u4yQEddGhQ4f0ta99Tddcc02b9wOBgM4//3wdOnRIb7zxhp5++mktXrxYt956a6hPXV2dzj//fE2ZMkUbN25URUWFvv3tb+ull15K1q+RUSZPniy/3x/2+Pa3v62RI0fq9NNPD+u7cuXKsH4TJkxI0agz15133hn2Hl577bWhe01NTTrnnHM0fPhwbdiwQffdd59uv/12Pf744ykccWbZvHmzmpub9dhjj+kf//iHfvKTn+jRRx/V//zP/0T05fPcdc8//7wWLFig2267TX/961918skna9q0adqzZ0+qh5axXnnlFc2dO1dvvvmmVqxYocOHD+ucc87RJ598EtZvzpw5YZ9b/qKk80444YSw9/C1114L3bv++uv1hz/8Qb/5zW/0yiuvaOfOnfJ4PCkcbWZav3592Hu8YsUKSdLXvva1UB8+y53zySef6OSTT9YjjzzS5v17771XDz30kB599FGtW7dORx99tKZNm6YDBw6E+lx++eX6xz/+oRUrVuiFF17Qq6++qquvvjq+AzXRLdXV1WZhYWFE+4svvmjm5eWZu3btCrX9/Oc/NwsKCsyDBw+apmmaP/jBD8wTTjgh7HmXXnqpOW3atISOOVscOnTIHDRokHnnnXeG2urq6kxJ5ttvv526gWWB4cOHmz/5yU/avf+zn/3MPOaYY0KfZdM0zZtuuskcM2ZMEkaXve69915z5MiRoWs+z933pS99yZw7d27oOhAImEOHDjUXLVqUwlFllz179piSzFdeeSXUdtZZZ5nz589P3aCywG233WaefPLJbd7bu3ev2bNnT/M3v/lNqK22ttaUZK5duzZJI8xO8+fPN0eNGmU2Nzebpslnubskmb/73e9C183NzWZxcbF53333hdr27t1r5ufnm88995xpmqb57rvvmpLM9evXh/r86U9/Mm02m+nz+eI2NmaCEmTt2rU68cQTNWTIkFDbtGnT1NTUpH/84x+hPlOnTg173rRp07R27dqkjjVTLVu2TB9++KG++c1vRty78MILNXjwYJ1xxhlatmxZCkaX+e655x4NGDBAp556qu67776wpZxr167VmWeeqV69eoXapk2bpi1btujjjz9OxXCzQmNjo/r37x/Rzue5aw4dOqQNGzaE/Xc2Ly9PU6dO5b+zcdTY2ChJEZ/dZ555RgMHDtT48eO1cOFCffrpp6kYXkbbunWrhg4dqmOPPVaXX3656uvrJUkbNmzQ4cOHwz7bY8eO1bBhw/hsd8OhQ4f0q1/9St/61rdks9lC7XyW46eurk67du0K++wWFhZq4sSJoc/u2rVrVVRUFLbKZ+rUqcrLy9O6deviNpYecXslhNm1a1dYAJIUut61a1eHfZqamvTZZ5+pd+/eyRlshnryySc1bdo0OZ3OUFvfvn31wAMP6Mtf/rLy8vL029/+VjNmzNDSpUt14YUXpnC0meW6667Taaedpv79++uNN97QwoUL5ff79eCDD0qyPrsjR44Me07Lz/cxxxyT9DFnum3btunhhx/W/fffH2rj89w9//73vxUIBNr87+zmzZtTNKrs0tzcrIqKCn35y1/W+PHjQ+0zZ87U8OHDNXToUG3atEk33XSTtmzZIsMwUjjazDJx4kQtXrxYY8aMkd/v1x133CG326133nlHu3btUq9evSL2JA8ZMiT0HQOdt3TpUu3du1ezZ88OtfFZjq/g57Ot/y63/H48ePDgsPs9evRQ//794/r5JgS1cPPNN+vHP/5xh31qa2vDNiai+7ryvn/wwQd66aWXtGTJkrB+AwcO1IIFC0LXX/ziF7Vz507dd999Of+lsTPvc8v38KSTTlKvXr30ne98R4sWLVJ+fn6ih5rRuvJ59vl8mj59ur72ta9pzpw5oXY+z0h3c+fO1TvvvBO2V0VS2Nr9E088UQ6HQ2effba2b9+uUaNGJXuYGencc88N/fNJJ52kiRMnavjw4VqyZAl/SZogTz75pM4991wNHTo01MZnOXsRglq44YYbwtJ/W4499tiYXqu4uDiiAlGwaktxcXHoz9aVXHbv3q2CgoKc+g9cV9736upqDRgwIKYvghMnTgxtdMxl3fl8T5w4UUeOHNGOHTs0ZsyYdj+70n8+37mqs+/zzp07NWXKFE2ePDmmwhJ8nmM3cOBA2e32Nj+ruf45jYd58+aFNiy3nJFvy8SJEyVZM558ceyaoqIiHX/88dq2bZu+8pWv6NChQ9q7d2/YbBCf7a57//33tXLlyqgzPHyWuyf4+dy9e7ccDkeofffu3TrllFNCfVoXrzly5Ig++uijuH6+CUEtDBo0SIMGDYrLa02aNEl333239uzZE5rSW7FihQoKCvSFL3wh1OfFF18Me96KFSs0adKkuIwhU3T2fTdNU9XV1bryyivVs2fPqP03btwY9j+0XNWdz/fGjRuVl5cX+ixPmjRJ/+///T8dPnw49O9gxYoVGjNmTM4vhevM++zz+TRlyhRNmDBB1dXVysuLvk2Tz3PsevXqpQkTJmjVqlWaMWOGJGv51qpVqzRv3rzUDi6Dmaapa6+9Vr/73e+0Zs2aiKWxbdm4caMk8dnthv3792v79u264oorNGHCBPXs2VOrVq3SxRdfLEnasmWL6uvrc+47RLxUV1dr8ODBOv/88zvsx2e5e0aOHKni4mKtWrUqFHqampq0bt26UMXlSZMmae/evdqwYUOoGurLL7+s5ubmUAiNi7iVWMgx77//vvn222+bd9xxh9m3b1/z7bffNt9++21z3759pmma5pEjR8zx48eb55xzjrlx40Zz+fLl5qBBg8yFCxeGXuOf//yn2adPH/P73/++WVtbaz7yyCOm3W43ly9fnqpfKyOsXLnSlGTW1tZG3Fu8eLH57LPPmrW1tWZtba159913m3l5eeZTTz2VgpFmpjfeeMP8yU9+Ym7cuNHcvn27+atf/cocNGiQeeWVV4b67N271xwyZIh5xRVXmO+8847561//2uzTp4/52GOPpXDkmeWDDz4wR48ebZ599tnmBx98YPr9/tAjiM9z9/3617828/PzzcWLF5vvvvuuefXVV5tFRUVhlTvROddcc41ZWFhorlmzJuxz++mnn5qmaZrbtm0z77zzTvMvf/mLWVdXZ/7+9783jz32WPPMM89M8cgzyw033GCuWbPGrKurM19//XVz6tSp5sCBA809e/aYpmma3/3ud81hw4aZL7/8svmXv/zFnDRpkjlp0qQUjzozBQIBc9iwYeZNN90U1s5nuWv27dsX+l4syXzwwQfNt99+23z//fdN0zTNe+65xywqKjJ///vfm5s2bTLLysrMkSNHmp999lnoNaZPn26eeuqp5rp168zXXnvNPO6448zLLrssruMkBHXRrFmzTEkRj9WrV4f67Nixwzz33HPN3r17mwMHDjRvuOEG8/Dhw2Gvs3r1avOUU04xe/XqZR577LFmdXV1cn+RDHTZZZeZkydPbvPe4sWLzXHjxpl9+vQxCwoKzC996UthJUQR3YYNG8yJEyeahYWF5lFHHWWOGzfO/N///V/zwIEDYf3+9re/mWeccYaZn59vlpSUmPfcc0+KRpyZqqur2/xvSMu/m+LzHB8PP/ywOWzYMLNXr17ml770JfPNN99M9ZAyWnuf2+D/f9XX15tnnnmm2b9/fzM/P98cPXq0+f3vf99sbGxM7cAzzKWXXmo6HA6zV69eZklJiXnppZea27ZtC93/7LPPzO9973vmMcccY/bp08e86KKLwv4SBbF76aWXTEnmli1bwtr5LHfN6tWr2/xvxKxZs0zTtMpk//CHPzSHDBli5ufnm2effXbEe//hhx+al112mdm3b1+zoKDA/OY3vxmaaIgXm2maZvzmlQAAAAAgvXFOEAAAAICcQggCAAAAkFMIQQAAAAByCiEIAAAAQE4hBAEAAADIKYQgAAAAADmFEAQAAAAgpxCCAAAAAOQUQhAAAACAnEIIAgAAAJBTCEEAAAAAcsr/B5JmPHBeFL1aAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EXxHBAtHoSh2",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d0a48914-c28c-4aae-cc1c-aa2adfd94b8c"
      },
      "source": [
        "# Calculate model_1 metrics\n",
        "mae_1 = mae(y_test, y_preds_1.squeeze()).numpy()\n",
        "mse_1 = mse(y_test, y_preds_1.squeeze()).numpy()\n",
        "mae_1, mse_1"
      ],
      "execution_count": 46,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(30.638134, 949.13086)"
            ]
          },
          "metadata": {},
          "execution_count": 46
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XXELOpdBrE9_"
      },
      "source": [
        "**Build `model_2`**\n",
        "\n",
        "This time we'll add an extra dense layer (so now our model will have 2 layers) whilst keeping everything else the same."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "05vcgEP3rEFi",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "38d3aede-85f2-4670-f1d0-168065fdec1b"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Replicate model_1 and add an extra layer\n",
        "model_2 = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1),\n",
        "  tf.keras.layers.Dense(1) # add a second layer\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "model_2.compile(loss=tf.keras.losses.mae,\n",
        "                optimizer=tf.keras.optimizers.SGD(),\n",
        "                metrics=['mae'])\n",
        "\n",
        "# Fit the model\n",
        "model_2.fit(tf.expand_dims(X_train, axis=-1), y_train, epochs=100, verbose=0) # set verbose to 0 for less output"
      ],
      "execution_count": 47,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f00643ba560>"
            ]
          },
          "metadata": {},
          "execution_count": 47
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9xCbDcoDraux",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 655
        },
        "outputId": "322c6548-42c1-42ec-8680-3a1e649a9607"
      },
      "source": [
        "# Make and plot predictions for model_2\n",
        "y_preds_2 = model_2.predict(X_test)\n",
        "plot_predictions(predictions=y_preds_2)"
      ],
      "execution_count": 48,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:tensorflow:5 out of the last 5 calls to <function Model.make_predict_function.<locals>.predict_function at 0x7f006436f880> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 51ms/step\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1000x700 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0oAAAJGCAYAAABlb3UiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABXKUlEQVR4nO3dfXyT5aHG8SsNUCglKSDQ0hSKyhAVX8DJKTNajhyLoqcSqw6cgnO6OVQqqIjH+XbmwfladDrcVOrZlMlYxjxOYcioVkVEtDq1MNRiaw3gUBpQoZA+54/HZE1T2rTNe37fz6efmid3krsxYi/u57kvi2EYhgAAAAAAARnxngAAAAAAJBqCEgAAAAC0QVACAAAAgDYISgAAAADQBkEJAAAAANogKAEAAABAGwQlAAAAAGijV7wnEAstLS367LPPNGDAAFkslnhPBwAAAECcGIahPXv2aPjw4crIOPS6UVoEpc8++0wFBQXxngYAAACABNHQ0CCHw3HI+9MiKA0YMECS+WbYbLY4zwYAAABAvHi9XhUUFAQywqGkRVDyn25ns9kISgAAAAA6vSSHzRwAAAAAoA2CEgAAAAC0QVACAAAAgDbS4hqlcLS0tKi5uTne00CC6927t6xWa7ynAQAAgCgjKElqbm5WXV2dWlpa4j0VJIGcnBzl5ubSyQUAAJDC0j4oGYYhj8cjq9WqgoKCDkunkN4Mw9DXX3+tnTt3SpLy8vLiPCMAAABES9oHpYMHD+rrr7/W8OHDlZWVFe/pIMH169dPkrRz504NHTqU0/AAAABSVNovn/h8PklSnz594jwTJAt/oD5w4ECcZwIAAIBoSfug5Mf1JggXnxUAAIDUR1ACAAAAgDYISggoLCxURUVF2OOrqqpksVi0e/fuqM3pUCorK5WTkxPz1wUAAEB6ICglIYvF0uHXbbfd1q3n3bhxo6644oqwx0+aNEkej0d2u71brxdrXQ2CAAAASF9pv+tdpPh8UnW15PFIeXmS0ylFa0M0j8cT+OdnnnlGt9xyi7Zs2RI4lp2dHfhnwzDk8/nUq1fn/6qHDBnSpXn06dNHubm5XXoMAAAAkAxYUYoAt1sqLJQmT5ZmzjS/Fxaax6MhNzc38GW322WxWAK3N2/erAEDBuiFF17QhAkTlJmZqVdeeUUfffSRSktLNWzYMGVnZ+u73/2uXnzxxaDnbbviYrFY9Nhjj2n69OnKysrS6NGj9eyzzwbub3vqnf90uNWrV2vs2LHKzs7W1KlTg4LdwYMHdc011ygnJ0eDBw/WggULNGvWLJ177rkd/syVlZUaMWKEsrKyNH36dO3atSvo/s5+vuLiYn3yySe69tprAytvkrRr1y7NmDFD+fn5ysrK0rhx47Rs2bKu/OsAAABACiIo9ZDbLZWVSZ9+Gny8sdE8Hq2w1Jkbb7xRd911l2pra3Xcccdp7969Ouuss7R27Vq9/fbbmjp1qs455xzV19d3+Dy33367LrjgAr377rs666yzdNFFF+mLL7445Pivv/5a9957r37729/q5ZdfVn19va677rrA/b/4xS/01FNPaenSpXr11Vfl9Xq1cuXKDuewYcMGXXbZZbrqqqtUU1OjyZMn6+c//3nQmM5+PrfbLYfDoTvuuEMejycQ3vbt26cJEyboL3/5i9577z1dccUVuvjii/XGG290OCcAAACkOCMNNDU1GZKMpqamkPu++eYb44MPPjC++eabLj/vwYOG4XAYhtT+l8ViGAUF5rhoWbp0qWG32wO3161bZ0gyVq5c2eljjznmGOOhhx4K3B45cqTxwAMPBG5LMm6++ebA7b179xqSjBdeeCHotb788svAXCQZH374YeAxDz/8sDFs2LDA7WHDhhn33HNP4PbBgweNESNGGKWlpYec54wZM4yzzjor6NiFF14Y9HN35+c7lGnTphnz588/5P09+cwAAAAgvjrKBq2xotQD1dWhK0mtGYbU0GCOi7WTTjop6PbevXt13XXXaezYscrJyVF2drZqa2s7XVE67rjjAv/cv39/2Ww27dy585Djs7KydMQRRwRu5+XlBcY3NTVpx44dOvnkkwP3W61WTZgwocM51NbWauLEiUHHioqKIvLz+Xw+/fd//7fGjRunQYMGKTs7W6tXr+70cQAAAEhtbObQA60uvYnIuEjq379/0O3rrrtOa9as0b333qsjjzxS/fr1U1lZmZqbmzt8nt69ewfdtlgsamlp6dJ4wzC6OPuu6+7Pd88992jx4sWqqKjQuHHj1L9/f5WXl3f6OAAAAIQhljueRRhBqQfy8iI7LppeffVVzZ49W9OnT5dkrsBs27YtpnOw2+0aNmyYNm7cqFNPPVWSuaLz1ltv6YQTTjjk48aOHasNGzYEHXv99deDbofz8/Xp00c+ny/kcaWlpfrBD34gSWppadE//vEPHX300d35EQEAAODndktz5wafguVwSIsXSy5X/OYVJk696wGn0/x3/e0GaiEsFqmgwBwXb6NHj5bb7VZNTY3eeecdzZw5s8OVoWi5+uqrtWjRIv35z3/Wli1bNHfuXH355ZeBXejac80112jVqlW69957tXXrVv3yl7/UqlWrgsaE8/MVFhbq5ZdfVmNjo/75z38GHrdmzRq99tprqq2t1Y9//GPt2LEj8j84AABAOknUHc+6gKDUA1arGYil0LDkv11RkRiri/fff78GDhyoSZMm6ZxzzlFJSYnGjx8f83ksWLBAM2bM0CWXXKKioiJlZ2erpKREffv2PeRj/u3f/k2/+c1vtHjxYh1//PH661//qptvvjloTDg/3x133KFt27bpiCOOCHRG3XzzzRo/frxKSkpUXFys3NzcTrcqBwAAQAd8PnMlqb3LL/zHysvNcQnMYsTiApI483q9stvtampqks1mC7pv3759qqur06hRozr8Zb0j7a0qFhSYISkJVhXjqqWlRWPHjtUFF1yg//7v/473dMISic8MAABAyqqqMotFO7NunVRcHO3ZhOgoG7TGNUoR4HJJpaVJe51aTH3yySf661//qtNOO0379+/XL3/5S9XV1WnmzJnxnhoAAAAiIZF3POsCglKEWK1xCcRJJyMjQ5WVlbruuutkGIaOPfZYvfjiixo7dmy8pwYAAIBISKYdzzpAUEJMFRQU6NVXX433NAAAABAt/h3PGhvbv07JYjHvT4QdzzrAZg4AAAAAIieZdjzrAEEJAAAAQGS5XNKKFVJ+fvBxh8M8ngQ7nnHqHQAAAIDIS/IdzwhKAAAAADrm83Uv8CTxjmcEJQAAAACH1l5pqMNhXoeUBKfQdRfXKAEAAABon9stlZUFhyTJ3NGurMy8P0URlNCp2267TSeccEJcXnv27Nk699xz4/LaAAAAac3nM1eS2tvi23+svNwcl4IISknIYrF0+HXbbbf16LlXrlwZdOy6667T2rVrezbpGNm2bZssFotqamriPRUAAIDkVl0dupLUmmFIDQ3muBTENUoR4mvxqbq+Wp49HuUNyJNzhFPWjOjs6OHxeAL//Mwzz+iWW27Rli1bAseys7Mj+nrZ2dkRf04AAAAkuFa/c0ZkXJJhRSkC3LVuFS4u1OQnJ2ume6YmPzlZhYsL5a6Nzjmbubm5gS+73S6LxRJ07Pe//73Gjh2rvn376qijjtIjjzwSeGxzc7Ouuuoq5eXlqW/fvho5cqQWLVokSSosLJQkTZ8+XRaLJXC77al3/tPh7r33XuXl5Wnw4MGaM2eODhw4EBjj8Xg0bdo09evXT6NGjdLTTz+twsJCVVRUHPLn8vl8mjdvnnJycjR48GDdcMMNMtos9a5atUqnnHJKYMzZZ5+tjz76KHD/qFGjJEknnniiLBaLir/dZWXjxo36j//4Dx122GGy2+067bTT9NZbb3X1rQcAAEgfeXmRHZdkCEo95K51q2x5mT71Bi9LNnobVba8LGph6VCeeuop3XLLLbrzzjtVW1ur//mf/9HPfvYzPfnkk5KkBx98UM8++6yWL1+uLVu26KmnngoEoo0bN0qSli5dKo/HE7jdnnXr1umjjz7SunXr9OSTT6qyslKVlZWB+y+55BJ99tlnqqqq0h//+Ef9+te/1s6dOzuc+3333afKyko98cQTeuWVV/TFF1/oT3/6U9CYr776SvPmzdObb76ptWvXKiMjQ9OnT1dLS4sk6Y033pAkvfjii/J4PHJ/e4Hhnj17NGvWLL3yyit6/fXXNXr0aJ111lnas2dP+G8uAABAOnE6zd3tLJb277dYpIICc1wK4tS7HvC1+DR31VwZCr3AzZAhiywqX1Wu0jGlUTsNr61bb71V9913n1zfbtU4atQoffDBB3r00Uc1a9Ys1dfXa/To0TrllFNksVg0cuTIwGOHDBkiScrJyVFubm6HrzNw4ED98pe/lNVq1VFHHaVp06Zp7dq1uvzyy7V582a9+OKL2rhxo0466SRJ0mOPPabRo0d3+JwVFRVauHBhYO5LlizR6tWrg8acd955QbefeOIJDRkyRB988IGOPfbYwM8wePDgoJ/h3//934Me9+tf/1o5OTl66aWXdPbZZ3c4LwAAgLRktZpbgJeVmaGo9Zk+/vBUUZE0BbJdxYpSD1TXV4esJLVmyFCDt0HV9bG5wO2rr77SRx99pMsuuyxwXVF2drZ+/vOfB05Pmz17tmpqajRmzBhdc801+utf/9qt1zrmmGNkbfUfRV5eXmDFaMuWLerVq5fGjx8fuP/II4/UwIEDD/l8TU1N8ng8mjhxYuBYr169AkHLb+vWrZoxY4YOP/xw2Wy2wGpYfX19h/PdsWOHLr/8co0ePVp2u102m0179+7t9HEAAABpzeWSVqyQ8vODjzsc5vEU7lFiRakHPHvCu3At3HE9tXfvXknSb37zm6DAISkQasaPH6+6ujq98MILevHFF3XBBRdoypQpWrFiRZdeq3fv3kG3LRZL4PS3aDrnnHM0cuRI/eY3v9Hw4cPV0tKiY489Vs3NzR0+btasWdq1a5cWL16skSNHKjMzU0VFRZ0+DgAAIO25XFJpqbm7ncdjXpPkdKbsSpIfQakH8gaEd+FauON6atiwYRo+fLg+/vhjXXTRRYccZ7PZdOGFF+rCCy9UWVmZpk6dqi+++EKDBg1S79695evhXvhjxozRwYMH9fbbb2vChAmSpA8//FBffvnlIR9jt9uVl5enDRs26NRTT5UkHTx4UJs2bQqsTO3atUtbtmzRb37zGzm/PRf2lVdeCXqePn36SFLIz/Dqq6/qkUce0VlnnSVJamho0D//+c8e/ZwAAABpw2qVvt0kK10QlHrAOcIph82hRm9ju9cpWWSRw+aQc0TsLnC7/fbbdc0118hut2vq1Knav3+/3nzzTX355ZeaN2+e7r//fuXl5enEE09URkaG/vCHPyg3N1c5OTmSzJ3v1q5dq+9973vKzMzs8HS5QznqqKM0ZcoUXXHFFfrVr36l3r17a/78+erXr58sh7oYUNLcuXN11113afTo0TrqqKN0//33a/fu3YH7Bw4cqMGDB+vXv/618vLyVF9frxtvvDHoOYYOHap+/fpp1apVcjgc6tu3r+x2u0aPHq3f/va3Oumkk+T1enX99derX79+Xf7ZAAAAkprPl3YrQ93FNUo9YM2wavHUxZLMUNSa/3bF1IqYbeQgST/60Y/02GOPaenSpRo3bpxOO+00VVZWBrbNHjBggO6++26ddNJJ+u53v6tt27bp+eefV0aG+VG47777tGbNGhUUFOjEE0/s9jz+93//V8OGDdOpp56q6dOn6/LLL9eAAQPUt2/fQz5m/vz5uvjiizVr1iwVFRVpwIABmj59euD+jIwM/f73v9emTZt07LHH6tprr9U999wT9By9evXSgw8+qEcffVTDhw9XaWmpJOnxxx/Xl19+qfHjx+viiy/WNddco6FDh3b75wMAAEg6brdUWChNnizNnGl+Lyw0jyOExWhbVJOCvF6v7Ha7mpqaZLPZgu7b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/Stavg52Xxk7dqwOHjwY9Lq7du3Sli1bdPTRR3f4M7V14oknauHChXrttdd07LHH6umnn+7S4wEAABKay2VuAZ6fH3zc4UiorcGtGVYtnmqGurZhyX+7YmqFrBnxD3UdISj1RBItgV500UU67LDDVFpaqurqatXV1amqqkrXXHONPv329MG5c+fqrrvu0sqVK7V582b99Kc/1e7duw/5nIWFhZo1a5Z++MMfauXKlYHnXL58uSRp5MiRslgseu655/T5559r7969Ic8xevRolZaW6vLLL9crr7yid955Rz/4wQ+Un5+v0tLSsH62uro6LVy4UOvXr9cnn3yiv/71r9q6dSvXKQEAgNTjcknbtknr1klPP21+r6uLekjqanGsa6xLKy5YoXxbcKhz2BxaccGKpOhRYjOHnvAvgZaVmaGo9aYOCbYEmpWVpZdfflkLFiyQy+XSnj17lJ+fr9NPP102m02SNH/+fHk8Hs2aNUsZGRn64Q9/qOnTp6upqemQz/urX/1KN910k376059q165dGjFihG666SZJUn5+vm6//XbdeOONuvTSS3XJJZeosrIy5DmWLl2quXPn6uyzz1Zzc7NOPfVUPf/882GX0mZlZWnz5s168skntWvXLuXl5WnOnDn68Y9/3PU3CgAAINFZrVJxccxerrvFsa6xLpWOKVV1fbU8ezzKG5An5whnwq8k+VmMtkU5Kcjr9cput6upqSkQCvz27dunuro6jRo1Sn379u3eC7jd5u53rTd2KCgwQ1KCLIEiciLymQEAAPD5zE2/PB7zUg2nMyH+gr01f3Fs204k/yl0ybI61FpH2aA1VpQiweUytwBP8A86AAAAEkR7f9HucJhnKyXIX7R3VhxrkUXlq8pVOqY0aVaJuoKgFCkxXgIFAABAknK7zUs32p7Y1dhoHk+QjRm6UhxbXFgcu4nFCJs5AAAAALHi85krSe1d/eI/Vl5ujouzVCmO7a6oBqWXX35Z55xzjoYPHy6LxaKVK1cG3W8Yhm655Rbl5eWpX79+mjJlirZu3Ro05osvvtBFF10km82mnJwcXXbZZe3ungYAAAAkvOrq4NPt2jIMqaHBHBdnqVIc211RDUpfffWVjj/+eD388MPt3n/33XfrwQcf1JIlS7Rhwwb1799fJSUl2rdvX2DMRRddpPfff19r1qzRc889p5dffllX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AABA9DZzuOWWW/Tkk08Gbp944omSpHXr1qm4uFhWq1XPPfecrrzyShUVFal///6aNWuW7rjjjsBjRo0apb/85S+69tprtXjxYjkcDj322GMqKSmJ1rQBAAAAIHpBqbKyUpWVlR2OGTlyZMipdW0VFxfr7bffjuDM4iszM1O33npr0DVUiDze59jgfY4N3ufo4z2ODd7n2OB9jg3e59iI5/sc9cJZAAAAAEg2cSucBQAAAIBERVACAAAAgDYISgAAAADQBkEJAAAAANogKAEAAABAGwSlKLnzzjs1adIkZWVlKScnp90x9fX1mjZtmrKysjR06FBdf/31OnjwYNCYqqoqjR8/XpmZmTryyCM73XI93VVVVclisbT7tXHjRknStm3b2r3/9ddfj/Psk0thYWHIe3jXXXcFjXn33XfldDrVt29fFRQU6O67747TbJPPtm3bdNlll2nUqFHq16+fjjjiCN16661qbm4OGsNnOTIefvhhFRYWqm/fvpo4caLeeOONeE8pqS1atEjf/e53NWDAAA0dOlTnnnuutmzZEjSmuLg45LP7k5/8JE4zTj633XZbyPt31FFHBe7ft2+f5syZo8GDBys7O1vnnXeeduzYEccZJ6f2/l9nsVg0Z84cSXyOu+vll1/WOeeco+HDh8tisWjlypVB9xuGoVtuuUV5eXnq16+fpkyZoq1btwaN+eKLL3TRRRfJZrMpJydHl112mfbu3RvReRKUoqS5uVnnn3++rrzyynbv9/l8mjZtmpqbm/Xaa6/pySefVGVlpW655ZbAmLq6Ok2bNk2TJ09WTU2NysvL9aMf/UirV6+O1Y+RdCZNmiSPxxP09aMf/UijRo3SSSedFDT2xRdfDBo3YcKEOM06ed1xxx1B7+HVV18duM/r9eqMM87QyJEjtWnTJt1zzz267bbb9Otf/zqOM04emzdvVktLix599FG9//77euCBB7RkyRLddNNNIWP5LPfMM888o3nz5unWW2/VW2+9peOPP14lJSXauXNnvKeWtF566SXNmTNHr7/+utasWaMDBw7ojDPO0FdffRU07vLLLw/67PKXKV1zzDHHBL1/r7zySuC+a6+9Vv/3f/+nP/zhD3rppZf02WefyeVyxXG2yWnjxo1B7/GaNWskSeeff35gDJ/jrvvqq690/PHH6+GHH273/rvvvlsPPviglixZ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GbW1tSH3VVZWGk8//bRRW1tr1NbWGnfeeaeRkZFhPPHEE3GYaXJ67bXXjAceeMCoqakxPvroI+N3v/udMWTIEOOSSy4JjNm9e7cxbNgw4+KLLzbee+894/e//72RlZVlPProo3GcefL49NNPjSOPPNI4/fTTjU8//dTweDyBLz8+y5Hx+9//3sjMzDQqKyuNDz74wLjiiiuMnJycoF1J0TVXXnmlYbfbjaqqqqDP7tdff20YhmF8+OGHxh133GG8+eabRl1dnfHnP//ZOPzww41TTz01zjNPHvPnzzeqqqqMuro649VXXzWmTJliHHbYYcbOnTsNwzCMn/zkJ8aIESOMv/3tb8abb75pFBUVGUVFRXGedXLy+XzGiBEjjAULFgQd53PcfXv27An8bizJuP/++423337b+OSTTwzDMIy77rrLyMnJMf785z8b7777rlFaWmqMGjXK+OabbwLPMXXqVOPEE080NmzYYLzyyivG6NGjjRkzZkR0ngSlKJk1a5YhKeRr3bp1gTHbtm0zzjzzTKNfv37GYYcdZsyfP984cOBA0POsW7fOOOGEE4w+ffoYhx9+uLF06dLY/iBJasaMGcakSZPava+ystIYO3askZWVZdhsNuPkk08O2kIVndu0aZMxceJEw263G3379jXGjh1r/M///I+xb9++oHHvvPOOccoppxiZmZlGfn6+cdddd8Vpxsln6dKl7f4Z0vrvt/gsR85DDz1kjBgxwujTp49x8sknG6+//nq8p5TUDvXZ9f8/rL6+3jj11FONQYMGGZmZmcaRRx5pXH/99UZTU1N8J55ELrzwQiMvL8/o06ePkZ+fb1x44YXGhx9+GLj/m2++MX76058aAwcONLKysozp06cH/UULwrd69WpDkrFly5ag43yOu2/dunXt/hkxa9YswzDMLcJ/9rOfGcOGDTMyMzON008/PeT937VrlzFjxgwjOzvbsNlsxqWXXhpYkIgUi2EYRuTWpwAAAAAg+dGjBAAAAABtEJQAAAAAoA2CEgAAAAC0QVACAAAAgDYISgAAAADQBkEJAAAAANogKAEAAABAGwQlAAAAAGiDoAQAAAAAbRCUAAAAAKANghIAAAAAtPH/axDHTOqvScoAAAAASUVORK5CYII=\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GxMYu5Frri6o"
      },
      "source": [
        "Woah, that's looking better already! And all it took was an extra layer."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9LnPuGaBrcrP",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "57f30e96-4218-45cd-8539-a18198dde62c"
      },
      "source": [
        "# Calculate model_2 metrics\n",
        "mae_2 = mae(y_test, y_preds_2.squeeze()).numpy()\n",
        "mse_2 = mse(y_test, y_preds_2.squeeze()).numpy()\n",
        "mae_2, mse_2"
      ],
      "execution_count": 49,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(10.610324, 120.35542)"
            ]
          },
          "metadata": {},
          "execution_count": 49
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "R8i9yfQGrwHx"
      },
      "source": [
        "**Build `model_3`**\n",
        "\n",
        "For our 3rd model, we'll keep everything the same as `model_2` except this time we'll train for longer (500 epochs instead of 100).\n",
        "\n",
        "This will give our model more of a chance to learn the patterns in the data."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ABGwQFsbrvUS",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "47e29c0e-bf45-4332-94a0-7a02e2d4f9b2"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Replicate model_2\n",
        "model_3 = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1),\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "model_3.compile(loss=tf.keras.losses.mae,\n",
        "                optimizer=tf.keras.optimizers.SGD(),\n",
        "                metrics=['mae'])\n",
        "\n",
        "# Fit the model (this time for 500 epochs, not 100)\n",
        "model_3.fit(tf.expand_dims(X_train, axis=-1), y_train, epochs=500, verbose=0) # set verbose to 0 for less output"
      ],
      "execution_count": 50,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f0065a5c8e0>"
            ]
          },
          "metadata": {},
          "execution_count": 50
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jEz4bVmasbFk",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 655
        },
        "outputId": "27d67368-f794-4a6d-e508-59c60458fd77"
      },
      "source": [
        "# Make and plot predictions for model_3\n",
        "y_preds_3 = model_3.predict(X_test)\n",
        "plot_predictions(predictions=y_preds_3)"
      ],
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:tensorflow:6 out of the last 6 calls to <function Model.make_predict_function.<locals>.predict_function at 0x7f00641280d0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 55ms/step\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 1000x700 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0EAAAJGCAYAAACdj47VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABjrUlEQVR4nO3de3yT9d3/8XcaaAXpQRBoaAJFUWDiETdumNFyywR1Wowd3uAUnMMdQKnoPeX+OU/bbpyntTo3dWrx3tSJ3TXG3IYDBI0KyJiMHQoCA1tDgE2lBZVTev3+uJasaVqStjnn9Xw88oDre32u9JsYaj/9fq/Px2aapikAAAAAyBF5qZ4AAAAAACQTSRAAAACAnEISBAAAACCnkAQBAAAAyCkkQQAAAAByCkkQAAAAgJxCEgQAAAAgp/RK9QR6qrW1Vbt27VJhYaFsNluqpwMAAAAgRUzT1P79+zVkyBDl5XW+3pPxSdCuXbvkcrlSPQ0AAAAAaaKpqUlOp7PT8xmfBBUWFkqyXmhRUVGKZwMAAAAgVVpaWuRyuUI5QmcyPgkKboErKioiCQIAAAAQ9TYZCiMAAAAAyCkkQQAAAAByCkkQAAAAgJyS8fcExSoQCOjIkSOpngbSWO/evWW321M9DQAAACRY1idBpmlq9+7d2rdvX6qnggxQUlKi0tJSek4BAABksaxPgoIJ0KBBg9S3b19+uEWHTNPUJ598or1790qSHA5HimcEAACARMnqJCgQCIQSoAEDBqR6Okhzffr0kSTt3btXgwYNYmscAABAlsrqwgjBe4D69u2b4pkgUwQ/K9w/BgAAkL2yOgkKYgscYsVnBQAAIPvlRBIEAAAAAEEkQTmivLxcNTU1McevXr1aNpstJVX1Fi1apJKSkqR/XQAAAOQGkqA0Y7PZjvm4++67u/W869ev1w033BBz/IQJE+T3+1VcXNytr5dsXU3yAAAAkLuyujpcvAQCktcr+f2SwyG53VKiCof5/f7Q31988UXdeeed2rJlS2isX79+ob+bpqlAIKBevaL/Zxw4cGCX5pGfn6/S0tIuXQMAAABkAlaCojAMqbxcmjhRmjHD+rO83BpPhNLS0tCjuLhYNpstdLx582YVFhbqd7/7ncaOHauCggK98cYb2r59uyorKzV48GD169dPn/3sZ7VixYqw522/UmKz2fTUU0/piiuuUN++fXXKKado6dKlofPtt8MFt6i98sorGj16tPr166cpU6aEJW1Hjx7VTTfdpJKSEg0YMEC33XabZs6cqalTpx7zNS9atEhDhw5V3759dcUVV+iDDz4IOx/t9VVUVOi9997TzTffHFoxk6QPPvhA06dPV1lZmfr27avTTz9dL7zwQlf+cwAAACALkQQdg2FIVVXS+++Hj/t81niiEqFobr/9dt13331qaGjQGWecoQMHDuiSSy7RypUr9c4772jKlCm67LLL1NjYeMznueeeezRt2jRt2rRJl1xyia6++mp9+OGHncZ/8sknevDBB/XTn/5Ur7/+uhobG3XrrbeGzn//+9/Xc889p7q6Or355ptqaWnRkiVLjjmHdevW6frrr9fcuXO1ceNGTZw4Ud/97nfDYqK9PsMw5HQ6de+998rv94cSs4MHD2rs2LH6zW9+o7/85S+64YYbdM011+jtt98+5pwAAACQ5cwM19zcbEoym5ubI859+umn5t/+9jfz008/7fLzHj1qmk6naUodP2w203S5rLhEqaurM4uLi0PHq1atMiWZS5YsiXrtaaedZj766KOh42HDhpk/+MEPQseSzDvuuCN0fODAAVOS+bvf/S7sa3300UehuUgyt23bFrrmscceMwcPHhw6Hjx4sPnAAw+Ejo8ePWoOHTrUrKys7HSe06dPNy+55JKwsauuuirsdXfn9XXm0ksvNW+55ZZOz/fkMwMAAIDUOlZu0BYrQZ3weiNXgNoyTampyYpLtnPPPTfs+MCBA7r11ls1evRolZSUqF+/fmpoaIi6EnTGGWeE/n788cerqKhIe/fu7TS+b9++Ovnkk0PHDocjFN/c3Kw9e/boc5/7XOi83W7X2LFjjzmHhoYGjRs3Lmxs/PjxcXl9gUBA3/nOd3T66aerf//+6tevn1555ZWo1wEAACC7URihE21udYlLXDwdf/zxYce33nqrli9frgcffFAjRoxQnz59VFVVpcOHDx/zeXr37h12bLPZ1Nra2qV40zS7OPuu6+7re+CBB1RbW6uamhqdfvrpOv7441VdXR31OgAAAMQm0BqQt9Er/36/HIUOuYe6Zc9LUAWxOCIJ6oTDEd+4RHrzzTc1a9YsXXHFFZKslZOdO3cmdQ7FxcUaPHiw1q9fr/PPP1+StRLzxz/+UWeddVan140ePVrr1q0LG1u7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OgEAADJFut3HngkSkgQNHz5cpaWlYf1nWlpatG7dOo0fP16SNH78eO3bty/sB+FXX31Vra2tESsdqZCOFTPuueceLVy4UI888ojeffdd/fnPf1ZdXZ0efvhhSdLDDz+sF154QZs3b9a7776rl156SaWlpSopKZFkVYhbuXKldu/efcyk5VhGjRqlSZMm6YYbbtDbb7+td955RzfccIP69Okjm63j90qS5s2bp/vuu09LlizR5s2b9c1vflP79u0LnT/hhBM0YMAAPfnkk9q2bZteffXVsBU/SRo0aJD69OmjZcuWac+ePWpubpYknXLKKfrpT3+qhoYGrVu3TldffbX69OnTrdcHAACQSaLdxy5J1cuqE9riJRN1Owk6cOCANm7cGGpcuWPHDm3cuFGNjY2y2Wyqrq7Wd7/7XS1dulR//vOfde2112rIkCGaOnWqJGn06NGaMmWKZs+erbfffltvvvmm5s6dq//6r//SkCFD4vHaeiQdK2Z89atf1VNPPaW6ujqdfvrpuuCCC7Ro0aLQSlBhYaHuv/9+nXvuufrsZz+rnTt36re//a3y8qz/zA899JCWL18ul8uls88+u9vz+L//+z8NHjxY559/vq644grNnj1bhYWFOu644zq95pZbbtE111yjmTNnavz48SosLAwrfpGXl6ef//zn2rBhg8aMGaObb75ZDzzwQNhz9OrVS4888oieeOIJDRkyRJWVlZKkp59+Wh999JHOOeccXXPNNbrpppsi7jcDAADIRl25jx3/ZjPbN2uJ0erVqzVx4sSI8ZkzZ2rRokUyTVN33XWXnnzySe3bt0/nnXeefvSjH+nUU08NxX744YeaO3eufv3rXysvL09XXnmlHnnkEfXr1y/mebS0tKi4uFjNzc0RW+MOHjyoHTt2aPjw4cf8Af1YOtpf6SpyZX3FjK54//335XK5tGLFCl144YWpnk6PxOMzAwAAkCwv/PkFzTBmRI173vO8pp8+PQkzSq1j5QZtdTsJSheJToKk7lXayGavvvqqDhw4oNNPP11+v1/f+ta35PP59O6770YUVcg0JEEAACCTrN65WhOfjVyYaG/VzFU5Ufwg1iQo46rDpUIuVsw4liNHjuh//ud/9Pe//12FhYWaMGGCnnvuuYxPgAAAADJN8D52X4uvw/uCbLLJWeRM6n3smYAkCF02efJkTZ48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pk6dqi1btoTFVFRURHxuv/71r6doxpnp7rvvjngPR40aFTp/8OBBzZkzRwMGDFC/fv105ZVXas+ePSmccWbq6P93NptNc+bMkcRnuTtef/11XXbZZRoyZIhsNpuWLFkSdt40Td15551yOBzq06ePJk2apK1bt4bFfPjhh7r66qtVVFSkkpISXX/99Tpw4EBc50kS1E2HDx/Wl770JX3jG9/o8HwgENCll16qw4cP66233tKzzz6rRYsW6c477wzF7NixQ5deeqkmTpyojRs3qrq6Wl/96lf1yiuvJOtlZJQJEybI7/eHPb761a9q+PDhOvfcc8NiV6xYERY3duzYFM06c917771h7+GNN94YOtfS0qKLLrpIw4YN04YNG/TAAw/o7rvv1pNPPpnCGWeWzZs3q7W1VU888YT++te/6gc/+IEef/xx/c///E9ELJ/n7nvxxRc1f/583XXXXfrjH/+oM888U5MnT9bevXtTPbWM9dprr2nOnDlau3atli9friNHjuiiiy7Sxx9/HBY3e/bssM8tvyjputNOOy3sPXzjjTdC526++Wb9+te/1ksvvaTXXntNu3btksfjSeFsM9P69evD3uPly5dLkr70pS+FYvgsd83HH3+sM888U4899liH5++//3498sgjevzxx7Vu3Todf/zxmjx5sg4ePBiKufrqq/XXv/5Vy5cv18svv6zXX39dN9xwQ3wnaqJH6urqzOLi4ojx3/72t2ZeXp65e/fu0NiPf/xjs6ioyDx06JBpmqb5rW99yzzttNPCrrvqqqvMyZMnJ3TO2eLw4cPmwIEDzXvvvTc0tmPHDlOS+c4776RuYllg2LBh5g9+8INOz//oRz8yTzjhhNBn2TRN87bbbjNHjhyZhNllr/vvv98cPnx46JjPc8997nOfM+fMmRM6DgQC5pAhQ8yFCxemcFbZZe/evaYk87XXXguNXXDBBea8efNSN6kscNddd5lnnnlmh+f27dtn9u7d23zppZdCYw0NDaYkc82aNUmaYXaaN2+eefLJJ5utra2mafJZ7ilJ5i9/+cvQcWtrq1laWmo+8MADobF9+/aZBQUF5gsvvGCapmn+7W9/MyWZ69evD8X87ne/M202m+nz+eI2N1aCEmTNmjU6/fTTNXjw4NDY5MmT1dLSor/+9a+hmEmTJoVdN3nyZK1Zsyapc81US5cu1QcffKDrrrsu4tzll1+uQYMG6bzzztPSpUtTMLvMd99992nAgAE6++yz9cADD4Rt5VyzZo3OP/985efnh8YmT56sLVu26KOPPkrFdLNCc3Oz+vfvHzHO57l7Dh8+rA0bNoR9n83Ly9OkSZP4PhtHzc3NkhTx2X3uued04oknasyYMVqwYIE++eSTVEwvo23dulVDhgzRSSedpKuvvlqNjY2SpA0bNujIkSNhn+1Ro0Zp6NChfLZ74PDhw/rZz36mr3zlK7LZbKFxPsvxs2PHDu3evTvss1tcXKxx48aFPrtr1qxRSUlJ2C6fSZMmKS8vT+vWrYvbXHrF7ZkQZvfu3WEJkKTQ8e7du48Z09LSok8//VR9+vRJzmQz1NNPP63JkyfL6XSGxvr166eHHnpIn//855WXl6df/OIXmjp1qpYsWaLLL788hbPNLDfddJPOOecc9e/fX2+99ZYWLFggv9+vhx9+WJL12R0+fHjYNW0/3yeccELS55zptm3bpkcffVQPPvhgaIzPc8/885//VCAQ6PD77ObNm1M0q+zS2tqq6upqff7zn9eYMWNC4zNmzNCwYcM0ZMgQbdq0Sbfddpu2bNkiwzBSONvMMm7cOC1atEgjR46U3+/XPffcI7fbrb/85S/avXu38vPzI+5JHjx4cOhnDHTdkiVLtG/fPs2aNSs0xmc5voKfz46+L7f9+XjQoEFh53v16qX+/fvH9fNNEtTG7bffru9///vHjGloaAi7MRE91533/f3339crr7yixYsXh8WdeOKJmj9/fuj4s5/9rHbt2qUHHngg539o7Mr73PY9POOMM5Sfn6+vfe1rWrhwoQoKChI91YzWnc+zz+fTlClT9KUvfUmzZ88OjfN5RrqbM2eO/vKXv4TdqyIpbO/+6aefLofDoQsvvFDbt2/XySefnOxpZqSLL7449PczzjhD48aN07Bhw7R48WJ+SZogTz/9tC6++GINGTIkNMZnOXuRBLVxyy23hGX/HTnppJNieq7S0tKICkTBqi2lpaWhP9tXctmzZ4+Kiopy6htcd973uro6DRgwIKYfBMeNGxe60TGX9eTzPW7cOB09elQ7d+7UyJEjO/3sSv/+fOeqrr7Pu3bt0sSJEzVhwoSYCkvweY7diSeeKLvd3uFnNdc/p/Ewd+7c0A3LbVfkOzJu3DhJ1oonPzh2T0lJiU499VRt27ZNX/jCF3T48GHt27cvbDWIz3b3vffee1qxYkXUFR4+yz0T/Hzu2bNHDocjNL5nzx6dddZZoZj2xWuOHj2qDz/8MK6fb5KgNgYOHKiBAwfG5bnGjx+v733ve9q7d29oSW/58uUqKirSZz7zmVDMb3/727Drli9frvHjx8dlDpmiq++7aZqqq6vTtddeq969e0eN37hxY9g/tFzVk8/3xo0blZeXF/osjx8/Xv/v//0/HTlyJPTfYPny5Ro5cmTOb4Xryvvs8/k0ceJEjR07VnV1dcrLi36bJp/n2OXn52vs2LFauXKlpk6dKsnavrVy5UrNnTs3tZPLYKZp6sYbb9Qvf/lLrV69OmJrbEc2btwoSXx2e+DAgQPavn27rrnmGo0dO1a9e/fWypUrdeWVV0qStmzZosbGxpz7GSJe6urqNGjQIF166aXHjOOz3DPDhw9XaWmpVq5cGUp6WlpatG7dulDF5fHjx2vfvn3asGFDqBrqq6++qtbW1lASGhdxK7GQY9577z3znXfeMe+55x6zX79+5jvvvGO+88475v79+03TNM2jR4+aY8aMMS+66CJz48aN5rJly8yBAweaCxYsCD3H3//+d7Nv377mf//3f5sNDQ3mY489ZtrtdnPZsmWpelkZYcWKFaYks6GhIeLcokWLzOeff95saGgwGxoazO9973tmXl6e+cwzz6RgppnprbfeMn/wgx+YGzduNLdv327+7Gc/MwcOHGhee+21oZh9+/aZgwcPNq+55hrzL3/5i/nzn//c7Nu3r/nEE0+kcOaZ5f333zdHjBhhXnjhheb7779v+v3+0COIz3PP/fznPzcLCgrMRYsWmX/729/MG264wSwpKQmr3Imu+cY3vmEWFxebq1evDvvcfvLJJ6Zpmua2bdvMe++91/zDH/5g7tixw/zVr35lnnTSSeb555+f4plnlltuucVcvXq1uWPHDvPNN980J02aZJ544onm3r17TdM0za9//evm0KFDzVdffdX8wx/+YI4fP94cP358imedmQKBgDl06FDztttuCxvns9w9+/fvD/1cLMl8+OGHzXfeecd87733TNM0zfvuu88sKSkxf/WrX5mbNm0yKysrzeHDh5uffvpp6DmmTJlinn322ea6devMN954wzzllFPM6dOnx3WeJEHdNHPmTFNSxGPVqlWhmJ07d5oXX3yx2adPH/PEE080b7nlFvPIkSNhz7Nq1SrzrLPOMvPz882TTjrJrKurS+4LyUDTp083J0yY0OG5RYsWmaNHjzb79u1rFhUVmZ/73OfCSogiug0bNpjjxo0zi4uLzeOOO84cPXq0+b//+7/mwYMHw+L+9Kc/meedd55ZUFBglpWVmffdd1+KZpyZ6urqOvwe0vZ3U3ye4+PRRx81hw4daubn55uf+9znzLVr16Z6Shmts89t8P9fjY2N5vnnn2/279/fLCgoMEeMGGH+93//t9nc3JzaiWeYq666ynQ4HGZ+fr5ZVlZmXnXVVea2bdtC5z/99FPzm9/8pnnCCSeYffv2Na+44oqwX6Igdq+88oopydyyZUvYOJ/l7lm1alWH3yNmzpxpmqZVJvvb3/62OXjwYLOgoMC88MILI977Dz74wJw+fbrZr18/s6ioyLzuuutCCw3xYjNN04zfuhIAAAAApDf6BAEAAADIKSRBAAAAAHIKSRAAAACAnEISBAAAACCnkAQBAAAAyCkkQQAAAAByCkkQAAAAgJxCEgQAAAAgp5AEAQAAAMgpJEEAAAAAcgpJEAAAAICc8v8B1OjgK2l0xqYAAAAASUVORK5CYII=\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "38Ki8ZHcsztG"
      },
      "source": [
        "Strange, we trained for longer but our model performed worse?\n",
        "\n",
        "As it turns out, our model might've trained too long and has thus resulted in worse results (we'll see ways to prevent training for too long later on)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BPTUcFe4sbfk",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "2e867a61-9fc2-4fbb-e193-63fb44fc643d"
      },
      "source": [
        "# Calculate model_3 metrics\n",
        "mae_3 = mae(y_test, y_preds_3.squeeze()).numpy()\n",
        "mse_3 = mse(y_test, y_preds_3.squeeze()).numpy()\n",
        "mae_3, mse_3"
      ],
      "execution_count": 52,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(67.224594, 4601.822)"
            ]
          },
          "metadata": {},
          "execution_count": 52
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UPEeM3UsrxGB"
      },
      "source": [
        "## Comparing results\n",
        "\n",
        "Now we've got results for 3 similar but slightly different results, let's compare them."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mw5RZk-BqLZd"
      },
      "source": [
        "model_results = [[\"model_1\", mae_1, mse_1],\n",
        "                 [\"model_2\", mae_2, mse_2],\n",
        "                 [\"model_3\", mae_3, mae_3]]"
      ],
      "execution_count": 53,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ip7bKH83p5X0",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 143
        },
        "outputId": "8783303f-53d2-44d3-a66c-f1bfec3b399e"
      },
      "source": [
        "import pandas as pd\n",
        "all_results = pd.DataFrame(model_results, columns=[\"model\", \"mae\", \"mse\"])\n",
        "all_results"
      ],
      "execution_count": 54,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "     model        mae         mse\n",
              "0  model_1  30.638134  949.130859\n",
              "1  model_2  10.610324  120.355423\n",
              "2  model_3  67.224594   67.224594"
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-6d298273-e93f-4ed5-9464-20e305f077e3\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>model</th>\n",
              "      <th>mae</th>\n",
              "      <th>mse</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>model_1</td>\n",
              "      <td>30.638134</td>\n",
              "      <td>949.130859</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>model_2</td>\n",
              "      <td>10.610324</td>\n",
              "      <td>120.355423</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>model_3</td>\n",
              "      <td>67.224594</td>\n",
              "      <td>67.224594</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-6d298273-e93f-4ed5-9464-20e305f077e3')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-6d298273-e93f-4ed5-9464-20e305f077e3 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-6d298273-e93f-4ed5-9464-20e305f077e3');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 54
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o_AtUiwuuLGo"
      },
      "source": [
        "From our experiments, it looks like `model_2` performed the best.\n",
        "\n",
        "And now, you might be thinking, \"wow, comparing models is tedious...\" and it definitely can be, we've only compared 3 models here. \n",
        "\n",
        "But this is part of what machine learning modelling is about, trying many different combinations of models and seeing which performs best.\n",
        "\n",
        "Each model you build is a small experiment. \n",
        "\n",
        "> 🔑 **Note:** One of your main goals should be to minimize the time between your experiments. The more experiments you do, the more things you'll figure out which don't work and in turn, get closer to figuring out what does work. Remember the machine learning practitioner's motto: \"experiment, experiment, experiment\".\n",
        "\n",
        "Another thing you'll also find is what you thought may work (such as training a model for longer) may not always work and the exact opposite is also often the case.\n",
        "\n",
        "## Tracking your experiments\n",
        "\n",
        "One really good habit to get into is tracking your modelling experiments to see which perform better than others.\n",
        "\n",
        "We've done a simple version of this above (keeping the results in different variables).\n",
        "\n",
        "> 📖 **Resource:** But as you build more models, you'll want to look into using tools such as:\n",
        "* [**TensorBoard**](https://tensorboard.dev/) - a component of the TensorFlow library to help track modelling experiments (we'll see this later).\n",
        "* [**Weights & Biases**](https://www.wandb.com/) - a tool for tracking all kinds of machine learning experiments (the good news for Weights & Biases is it plugs into TensorBoard)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Fe5DgNbX6192"
      },
      "source": [
        "## Saving a model\n",
        "\n",
        "Once you've trained a model and found one which performs to your liking, you'll probably want to save it for use elsewhere (like a web application or mobile device).\n",
        "\n",
        "You can save a TensorFlow/Keras model using [`model.save()`](https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model).\n",
        "\n",
        "There are two ways to save a model in TensorFlow:\n",
        "1. The [SavedModel format](https://www.tensorflow.org/tutorials/keras/save_and_load#savedmodel_format) (default).\n",
        "2. The [HDF5 format](https://www.tensorflow.org/tutorials/keras/save_and_load#hdf5_format).\n",
        "\n",
        "The main difference between the two is the SavedModel is automatically able to save custom objects (such as special layers) without additional modifications when loading the model back in.\n",
        "\n",
        "Which one should you use?\n",
        "\n",
        "It depends on your situation but the SavedModel format will suffice most of the time.\n",
        "\n",
        "Both methods use the same method call."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gg0jD2cUoPsg",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "261f2136-244e-40da-9aab-51b629b8e2ca"
      },
      "source": [
        "# Save a model using the SavedModel format\n",
        "model_2.save('best_model_SavedModel_format')"
      ],
      "execution_count": 55,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "WARNING:absl:Found untraced functions such as _update_step_xla while saving (showing 1 of 1). These functions will not be directly callable after loading.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dsCpDYrU7D1j",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "66b3eb4b-b4e8-4f1d-d86f-714d10708981"
      },
      "source": [
        "# Check it out - outputs a protobuf binary file (.pb) as well as other files\n",
        "!ls best_model_SavedModel_format"
      ],
      "execution_count": 56,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "assets\tfingerprint.pb\tkeras_metadata.pb  saved_model.pb  variables\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NGKmWco_SOEU"
      },
      "source": [
        "Now let's save the model in the HDF5 format, we'll use the same method but with a different filename."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "97J6GJMBSM2j"
      },
      "source": [
        "# Save a model using the HDF5 format\n",
        "model_2.save(\"best_model_HDF5_format.h5\") # note the addition of '.h5' on the end"
      ],
      "execution_count": 57,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "vB7TmsSGSjdv",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "15b7edff-d290-4ae0-a3c9-0ee71af9ecb6"
      },
      "source": [
        "# Check it out\n",
        "!ls best_model_HDF5_format.h5"
      ],
      "execution_count": 58,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "best_model_HDF5_format.h5\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OGA02tY97EUI"
      },
      "source": [
        "## Loading a model\n",
        "\n",
        "We can load a saved model using the [`load_model()`](https://www.tensorflow.org/api_docs/python/tf/keras/models/load_model) method.\n",
        "\n",
        "Loading a model for the different formats (SavedModel and HDF5) is the same (as long as the pathnames to the particular formats are correct)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FzyLIWfs7Fvh",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "de1e3965-fe8f-49fd-ce96-a55f39734ca7"
      },
      "source": [
        "# Load a model from the SavedModel format\n",
        "loaded_saved_model = tf.keras.models.load_model(\"best_model_SavedModel_format\")\n",
        "loaded_saved_model.summary()"
      ],
      "execution_count": 59,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model: \"sequential_5\"\n",
            "_________________________________________________________________\n",
            " Layer (type)                Output Shape              Param #   \n",
            "=================================================================\n",
            " dense_5 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            " dense_6 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            "=================================================================\n",
            "Total params: 4\n",
            "Trainable params: 4\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MfGO0dCQTeQh"
      },
      "source": [
        "Now let's test it out."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7rehN8ZxTy43",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "23cd7811-f6d6-4dcc-816f-e2fde1492b03"
      },
      "source": [
        "# Compare model_2 with the SavedModel version (should return True)\n",
        "model_2_preds = model_2.predict(X_test)\n",
        "saved_model_preds = loaded_saved_model.predict(X_test)\n",
        "mae(y_test, saved_model_preds.squeeze()).numpy() == mae(y_test, model_2_preds.squeeze()).numpy()"
      ],
      "execution_count": 60,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 34ms/step\n",
            "1/1 [==============================] - 0s 56ms/step\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {},
          "execution_count": 60
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "prjkfX6rUZ6a"
      },
      "source": [
        "Loading in from the HDF5 is much the same."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dQfx-bWKUfRQ",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b418e506-026d-4c80-cf7d-b733381564b4"
      },
      "source": [
        "# Load a model from the HDF5 format\n",
        "loaded_h5_model = tf.keras.models.load_model(\"best_model_HDF5_format.h5\")\n",
        "loaded_h5_model.summary()"
      ],
      "execution_count": 61,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model: \"sequential_5\"\n",
            "_________________________________________________________________\n",
            " Layer (type)                Output Shape              Param #   \n",
            "=================================================================\n",
            " dense_5 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            " dense_6 (Dense)             (None, 1)                 2         \n",
            "                                                                 \n",
            "=================================================================\n",
            "Total params: 4\n",
            "Trainable params: 4\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "L0kT91h-Uru-",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "2c11f0b5-e847-4986-a904-dab855b859bc"
      },
      "source": [
        "# Compare model_2 with the loaded HDF5 version (should return True)\n",
        "h5_model_preds = loaded_h5_model.predict(X_test)\n",
        "mae(y_test, h5_model_preds.squeeze()).numpy() == mae(y_test, model_2_preds.squeeze()).numpy()"
      ],
      "execution_count": 62,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "1/1 [==============================] - 0s 53ms/step\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "True"
            ]
          },
          "metadata": {},
          "execution_count": 62
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ABtsYBDtr5Zz"
      },
      "source": [
        "## Downloading a model (from Google Colab)\n",
        "\n",
        "Say you wanted to get your model from Google Colab to your local machine, you can do one of the following things:\n",
        "* Right click on the file in the files pane and click 'download'.\n",
        "* Use the code below."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JV0onjIIr9XC",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "outputId": "96827c1d-68a4-4823-bccb-c9f8b7299c25"
      },
      "source": [
        "# Download the model (or any file) from Google Colab\n",
        "from google.colab import files\n",
        "files.download(\"best_model_HDF5_format.h5\")"
      ],
      "execution_count": 63,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "\n",
              "    async function download(id, filename, size) {\n",
              "      if (!google.colab.kernel.accessAllowed) {\n",
              "        return;\n",
              "      }\n",
              "      const div = document.createElement('div');\n",
              "      const label = document.createElement('label');\n",
              "      label.textContent = `Downloading \"${filename}\": `;\n",
              "      div.appendChild(label);\n",
              "      const progress = document.createElement('progress');\n",
              "      progress.max = size;\n",
              "      div.appendChild(progress);\n",
              "      document.body.appendChild(div);\n",
              "\n",
              "      const buffers = [];\n",
              "      let downloaded = 0;\n",
              "\n",
              "      const channel = await google.colab.kernel.comms.open(id);\n",
              "      // Send a message to notify the kernel that we're ready.\n",
              "      channel.send({})\n",
              "\n",
              "      for await (const message of channel.messages) {\n",
              "        // Send a message to notify the kernel that we're ready.\n",
              "        channel.send({})\n",
              "        if (message.buffers) {\n",
              "          for (const buffer of message.buffers) {\n",
              "            buffers.push(buffer);\n",
              "            downloaded += buffer.byteLength;\n",
              "            progress.value = downloaded;\n",
              "          }\n",
              "        }\n",
              "      }\n",
              "      const blob = new Blob(buffers, {type: 'application/binary'});\n",
              "      const a = document.createElement('a');\n",
              "      a.href = window.URL.createObjectURL(blob);\n",
              "      a.download = filename;\n",
              "      div.appendChild(a);\n",
              "      a.click();\n",
              "      div.remove();\n",
              "    }\n",
              "  "
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.Javascript object>"
            ],
            "application/javascript": [
              "download(\"download_70fb08d7-6b9f-455b-8282-a93170225ab0\", \"best_model_HDF5_format.h5\", 21952)"
            ]
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7xpVdMtKw6X4"
      },
      "source": [
        "## A larger example\n",
        "\n",
        "Alright, we've seen the fundamentals of building neural network regression models in TensorFlow.\n",
        "\n",
        "Let's step it up a notch and build a model for a more feature rich dataset.\n",
        "\n",
        "More specifically we're going to try predict the cost of medical insurance for individuals based on a number of different parameters such as, `age`, `sex`, `bmi`, `children`, `smoking_status` and `residential_region`.\n",
        "\n",
        "To do, we'll leverage the pubically available [Medical Cost dataset](https://www.kaggle.com/mirichoi0218/insurance) available from Kaggle and [hosted on GitHub](https://github.com/stedy/Machine-Learning-with-R-datasets/blob/master/insurance.csv).\n",
        "\n",
        "> 🔑 **Note:** When learning machine learning paradigms, you'll often go through a series of foundational techniques and then practice them by working with open-source datasets and examples. Just as we're doing now, learn foundations, put them to work with different problems. Every time you work on something new, it's a good idea to search for something like \"problem X example with Python/TensorFlow\" where you substitute X for your problem."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WWK1LBxapgc2"
      },
      "source": [
        "# Import required libraries\n",
        "import tensorflow as tf\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt"
      ],
      "execution_count": 64,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JrnTr5N9blFo"
      },
      "source": [
        "# Read in the insurance dataset\n",
        "insurance = pd.read_csv(\"https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/insurance.csv\")"
      ],
      "execution_count": 65,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QtXPN7cfb4Nm",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "outputId": "68eb5a00-f480-48fb-ab5f-adbc9d256fd7"
      },
      "source": [
        "# Check out the insurance dataset\n",
        "insurance.head()"
      ],
      "execution_count": 66,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   age     sex     bmi  children smoker     region      charges\n",
              "0   19  female  27.900         0    yes  southwest  16884.92400\n",
              "1   18    male  33.770         1     no  southeast   1725.55230\n",
              "2   28    male  33.000         3     no  southeast   4449.46200\n",
              "3   33    male  22.705         0     no  northwest  21984.47061\n",
              "4   32    male  28.880         0     no  northwest   3866.85520"
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-8585ff66-bf6f-4b20-864e-d12a2b13f9fc\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>age</th>\n",
              "      <th>sex</th>\n",
              "      <th>bmi</th>\n",
              "      <th>children</th>\n",
              "      <th>smoker</th>\n",
              "      <th>region</th>\n",
              "      <th>charges</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>19</td>\n",
              "      <td>female</td>\n",
              "      <td>27.900</td>\n",
              "      <td>0</td>\n",
              "      <td>yes</td>\n",
              "      <td>southwest</td>\n",
              "      <td>16884.92400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>18</td>\n",
              "      <td>male</td>\n",
              "      <td>33.770</td>\n",
              "      <td>1</td>\n",
              "      <td>no</td>\n",
              "      <td>southeast</td>\n",
              "      <td>1725.55230</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>28</td>\n",
              "      <td>male</td>\n",
              "      <td>33.000</td>\n",
              "      <td>3</td>\n",
              "      <td>no</td>\n",
              "      <td>southeast</td>\n",
              "      <td>4449.46200</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>33</td>\n",
              "      <td>male</td>\n",
              "      <td>22.705</td>\n",
              "      <td>0</td>\n",
              "      <td>no</td>\n",
              "      <td>northwest</td>\n",
              "      <td>21984.47061</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>32</td>\n",
              "      <td>male</td>\n",
              "      <td>28.880</td>\n",
              "      <td>0</td>\n",
              "      <td>no</td>\n",
              "      <td>northwest</td>\n",
              "      <td>3866.85520</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-8585ff66-bf6f-4b20-864e-d12a2b13f9fc')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-8585ff66-bf6f-4b20-864e-d12a2b13f9fc button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-8585ff66-bf6f-4b20-864e-d12a2b13f9fc');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 66
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "s55oIsYv0KkZ"
      },
      "source": [
        "We're going to have to turn the non-numerical columns into numbers (because a neural network can't handle non-numerical inputs).\n",
        "\n",
        "To do so, we'll use the [`get_dummies()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html) method in pandas.\n",
        "\n",
        "It converts categorical variables (like the `sex`, `smoker` and `region` columns) into numerical variables using one-hot encoding."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MqM_BmPkdon8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 270
        },
        "outputId": "2be858a1-b1d9-4687-9020-7c642bfdc019"
      },
      "source": [
        "# Turn all categories into numbers\n",
        "insurance_one_hot = pd.get_dummies(insurance)\n",
        "insurance_one_hot.head() # view the converted columns"
      ],
      "execution_count": 67,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   age     bmi  children      charges  sex_female  sex_male  smoker_no  \\\n",
              "0   19  27.900         0  16884.92400           1         0          0   \n",
              "1   18  33.770         1   1725.55230           0         1          1   \n",
              "2   28  33.000         3   4449.46200           0         1          1   \n",
              "3   33  22.705         0  21984.47061           0         1          1   \n",
              "4   32  28.880         0   3866.85520           0         1          1   \n",
              "\n",
              "   smoker_yes  region_northeast  region_northwest  region_southeast  \\\n",
              "0           1                 0                 0                 0   \n",
              "1           0                 0                 0                 1   \n",
              "2           0                 0                 0                 1   \n",
              "3           0                 0                 1                 0   \n",
              "4           0                 0                 1                 0   \n",
              "\n",
              "   region_southwest  \n",
              "0                 1  \n",
              "1                 0  \n",
              "2                 0  \n",
              "3                 0  \n",
              "4                 0  "
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-c92f1586-abdd-470c-8ec2-39b1036ea2cc\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>age</th>\n",
              "      <th>bmi</th>\n",
              "      <th>children</th>\n",
              "      <th>charges</th>\n",
              "      <th>sex_female</th>\n",
              "      <th>sex_male</th>\n",
              "      <th>smoker_no</th>\n",
              "      <th>smoker_yes</th>\n",
              "      <th>region_northeast</th>\n",
              "      <th>region_northwest</th>\n",
              "      <th>region_southeast</th>\n",
              "      <th>region_southwest</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>19</td>\n",
              "      <td>27.900</td>\n",
              "      <td>0</td>\n",
              "      <td>16884.92400</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>18</td>\n",
              "      <td>33.770</td>\n",
              "      <td>1</td>\n",
              "      <td>1725.55230</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>28</td>\n",
              "      <td>33.000</td>\n",
              "      <td>3</td>\n",
              "      <td>4449.46200</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>33</td>\n",
              "      <td>22.705</td>\n",
              "      <td>0</td>\n",
              "      <td>21984.47061</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>32</td>\n",
              "      <td>28.880</td>\n",
              "      <td>0</td>\n",
              "      <td>3866.85520</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-c92f1586-abdd-470c-8ec2-39b1036ea2cc')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-c92f1586-abdd-470c-8ec2-39b1036ea2cc button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-c92f1586-abdd-470c-8ec2-39b1036ea2cc');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 67
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zOHoPzgqgZPq"
      },
      "source": [
        "Now we'll split data into features (`X`) and labels (`y`)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "W_EGj3FxhkAb"
      },
      "source": [
        "# Create X & y values\n",
        "X = insurance_one_hot.drop(\"charges\", axis=1)\n",
        "y = insurance_one_hot[\"charges\"]"
      ],
      "execution_count": 68,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 270
        },
        "id": "-QQFJmDn5ATV",
        "outputId": "03ac7d61-65d9-4923-a7e5-3e7ded7e52e3"
      },
      "source": [
        "# View features\n",
        "X.head()"
      ],
      "execution_count": 69,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   age     bmi  children  sex_female  sex_male  smoker_no  smoker_yes  \\\n",
              "0   19  27.900         0           1         0          0           1   \n",
              "1   18  33.770         1           0         1          1           0   \n",
              "2   28  33.000         3           0         1          1           0   \n",
              "3   33  22.705         0           0         1          1           0   \n",
              "4   32  28.880         0           0         1          1           0   \n",
              "\n",
              "   region_northeast  region_northwest  region_southeast  region_southwest  \n",
              "0                 0                 0                 0                 1  \n",
              "1                 0                 0                 1                 0  \n",
              "2                 0                 0                 1                 0  \n",
              "3                 0                 1                 0                 0  \n",
              "4                 0                 1                 0                 0  "
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-0cd98a93-5cb7-45e7-b1ad-09fb303f3923\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>age</th>\n",
              "      <th>bmi</th>\n",
              "      <th>children</th>\n",
              "      <th>sex_female</th>\n",
              "      <th>sex_male</th>\n",
              "      <th>smoker_no</th>\n",
              "      <th>smoker_yes</th>\n",
              "      <th>region_northeast</th>\n",
              "      <th>region_northwest</th>\n",
              "      <th>region_southeast</th>\n",
              "      <th>region_southwest</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>19</td>\n",
              "      <td>27.900</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>18</td>\n",
              "      <td>33.770</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>28</td>\n",
              "      <td>33.000</td>\n",
              "      <td>3</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>33</td>\n",
              "      <td>22.705</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>32</td>\n",
              "      <td>28.880</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-0cd98a93-5cb7-45e7-b1ad-09fb303f3923')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-0cd98a93-5cb7-45e7-b1ad-09fb303f3923 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-0cd98a93-5cb7-45e7-b1ad-09fb303f3923');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 69
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kudhkM-0giS1"
      },
      "source": [
        "And create training and test sets. We could do this manually, but to make it easier, we'll leverage the already available [`train_test_split`](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) function available from Scikit-Learn."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "WPGZGk0jhxCZ"
      },
      "source": [
        "# Create training and test sets\n",
        "from sklearn.model_selection import train_test_split\n",
        "X_train, X_test, y_train, y_test = train_test_split(X, \n",
        "                                                    y, \n",
        "                                                    test_size=0.2, \n",
        "                                                    random_state=42) # set random state for reproducible splits"
      ],
      "execution_count": 70,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "W8wEC0FPglnN"
      },
      "source": [
        "Now we can build and fit a model (we'll make it the same as `model_2`)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OCXTmz6oh_T6",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "b5be8e80-4c3c-43d1-9194-571574df2bec"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Create a new model (same as model_2)\n",
        "insurance_model = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(1),\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "insurance_model.compile(loss=tf.keras.losses.mae,\n",
        "                        optimizer=tf.keras.optimizers.SGD(),\n",
        "                        metrics=['mae'])\n",
        "\n",
        "# Fit the model\n",
        "insurance_model.fit(X_train, y_train, epochs=100)"
      ],
      "execution_count": 71,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/100\n",
            "34/34 [==============================] - 1s 3ms/step - loss: 9369.4971 - mae: 9369.4971\n",
            "Epoch 2/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7851.0615 - mae: 7851.0615\n",
            "Epoch 3/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7567.6006 - mae: 7567.6006\n",
            "Epoch 4/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7540.6812 - mae: 7540.6812\n",
            "Epoch 5/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7695.3062 - mae: 7695.3062\n",
            "Epoch 6/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7608.9712 - mae: 7608.9712\n",
            "Epoch 7/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7517.2896 - mae: 7517.2896\n",
            "Epoch 8/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7788.9150 - mae: 7788.9150\n",
            "Epoch 9/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7584.7583 - mae: 7584.7583\n",
            "Epoch 10/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7721.3062 - mae: 7721.3062\n",
            "Epoch 11/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7769.6841 - mae: 7769.6841\n",
            "Epoch 12/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7637.6289 - mae: 7637.6289\n",
            "Epoch 13/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7783.9155 - mae: 7783.9155\n",
            "Epoch 14/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7717.6284 - mae: 7717.6284\n",
            "Epoch 15/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7542.4185 - mae: 7542.4185\n",
            "Epoch 16/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7749.9731 - mae: 7749.9731\n",
            "Epoch 17/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7598.9355 - mae: 7598.9355\n",
            "Epoch 18/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7808.7837 - mae: 7808.7837\n",
            "Epoch 19/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7794.0264 - mae: 7794.0264\n",
            "Epoch 20/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7882.9180 - mae: 7882.9180\n",
            "Epoch 21/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7522.1748 - mae: 7522.1748\n",
            "Epoch 22/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7838.5420 - mae: 7838.5420\n",
            "Epoch 23/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7580.5273 - mae: 7580.5273\n",
            "Epoch 24/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7542.0605 - mae: 7542.0605\n",
            "Epoch 25/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7628.8145 - mae: 7628.8145\n",
            "Epoch 26/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7606.2163 - mae: 7606.2163\n",
            "Epoch 27/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7559.1895 - mae: 7559.1895\n",
            "Epoch 28/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7375.6968 - mae: 7375.6968\n",
            "Epoch 29/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7684.6680 - mae: 7684.6680\n",
            "Epoch 30/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7640.9189 - mae: 7640.9189\n",
            "Epoch 31/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7714.8374 - mae: 7714.8374\n",
            "Epoch 32/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7506.1108 - mae: 7506.1108\n",
            "Epoch 33/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7406.3838 - mae: 7406.3838\n",
            "Epoch 34/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7449.5298 - mae: 7449.5298\n",
            "Epoch 35/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7560.9849 - mae: 7560.9849\n",
            "Epoch 36/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7600.5376 - mae: 7600.5376\n",
            "Epoch 37/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7553.1353 - mae: 7553.1353\n",
            "Epoch 38/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7440.0786 - mae: 7440.0786\n",
            "Epoch 39/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7537.5098 - mae: 7537.5098\n",
            "Epoch 40/100\n",
            "34/34 [==============================] - 0s 2ms/step - loss: 7317.4824 - mae: 7317.4824\n",
            "Epoch 41/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7758.7363 - mae: 7758.7363\n",
            "Epoch 42/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7428.0835 - mae: 7428.0835\n",
            "Epoch 43/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7663.6904 - mae: 7663.6904\n",
            "Epoch 44/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7451.4316 - mae: 7451.4316\n",
            "Epoch 45/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7423.6045 - mae: 7423.6045\n",
            "Epoch 46/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7639.4028 - mae: 7639.4028\n",
            "Epoch 47/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7432.8540 - mae: 7432.8540\n",
            "Epoch 48/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7417.3125 - mae: 7417.3125\n",
            "Epoch 49/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7534.0508 - mae: 7534.0508\n",
            "Epoch 50/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7494.0288 - mae: 7494.0288\n",
            "Epoch 51/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7388.7905 - mae: 7388.7905\n",
            "Epoch 52/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7539.9224 - mae: 7539.9224\n",
            "Epoch 53/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7613.3428 - mae: 7613.3428\n",
            "Epoch 54/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7376.6582 - mae: 7376.6582\n",
            "Epoch 55/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7305.9424 - mae: 7305.9424\n",
            "Epoch 56/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7302.3154 - mae: 7302.3154\n",
            "Epoch 57/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7345.5010 - mae: 7345.5010\n",
            "Epoch 58/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7603.5664 - mae: 7603.5664\n",
            "Epoch 59/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7538.8198 - mae: 7538.8198\n",
            "Epoch 60/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7510.0747 - mae: 7510.0747\n",
            "Epoch 61/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7485.2583 - mae: 7485.2583\n",
            "Epoch 62/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7396.9038 - mae: 7396.9038\n",
            "Epoch 63/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7275.6465 - mae: 7275.6465\n",
            "Epoch 64/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7422.1836 - mae: 7422.1836\n",
            "Epoch 65/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7321.6035 - mae: 7321.6035\n",
            "Epoch 66/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7287.3623 - mae: 7287.3623\n",
            "Epoch 67/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7259.7354 - mae: 7259.7354\n",
            "Epoch 68/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7494.6240 - mae: 7494.6240\n",
            "Epoch 69/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7641.2607 - mae: 7641.2607\n",
            "Epoch 70/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7518.6045 - mae: 7518.6045\n",
            "Epoch 71/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7506.5884 - mae: 7506.5884\n",
            "Epoch 72/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7324.0532 - mae: 7324.0532\n",
            "Epoch 73/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7277.3755 - mae: 7277.3755\n",
            "Epoch 74/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7425.9590 - mae: 7425.9590\n",
            "Epoch 75/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7308.2617 - mae: 7308.2617\n",
            "Epoch 76/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7206.4956 - mae: 7206.4956\n",
            "Epoch 77/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7439.0884 - mae: 7439.0884\n",
            "Epoch 78/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7026.8892 - mae: 7026.8892\n",
            "Epoch 79/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7536.8247 - mae: 7536.8247\n",
            "Epoch 80/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7216.5439 - mae: 7216.5439\n",
            "Epoch 81/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7262.0186 - mae: 7262.0186\n",
            "Epoch 82/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7100.8447 - mae: 7100.8447\n",
            "Epoch 83/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7499.2349 - mae: 7499.2349\n",
            "Epoch 84/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7417.9360 - mae: 7417.9360\n",
            "Epoch 85/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7291.6318 - mae: 7291.6318\n",
            "Epoch 86/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7259.4048 - mae: 7259.4048\n",
            "Epoch 87/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7278.6729 - mae: 7278.6729\n",
            "Epoch 88/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7334.4409 - mae: 7334.4409\n",
            "Epoch 89/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7472.9878 - mae: 7472.9878\n",
            "Epoch 90/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7145.0088 - mae: 7145.0088\n",
            "Epoch 91/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7247.7705 - mae: 7247.7705\n",
            "Epoch 92/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7322.7412 - mae: 7322.7412\n",
            "Epoch 93/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7422.8809 - mae: 7422.8809\n",
            "Epoch 94/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7359.2515 - mae: 7359.2515\n",
            "Epoch 95/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7475.3711 - mae: 7475.3711\n",
            "Epoch 96/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 6932.3413 - mae: 6932.3413\n",
            "Epoch 97/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7036.0708 - mae: 7036.0708\n",
            "Epoch 98/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7209.4790 - mae: 7209.4790\n",
            "Epoch 99/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7393.4707 - mae: 7393.4707\n",
            "Epoch 100/100\n",
            "34/34 [==============================] - 0s 3ms/step - loss: 7257.4365 - mae: 7257.4365\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f002a284730>"
            ]
          },
          "metadata": {},
          "execution_count": 71
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "B1U7LqpKid0r",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "bb258865-ef03-43ef-a6d2-2cc1fa700008"
      },
      "source": [
        "# Check the results of the insurance model\n",
        "insurance_model.evaluate(X_test, y_test)"
      ],
      "execution_count": 72,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "9/9 [==============================] - 0s 2ms/step - loss: 6392.2939 - mae: 6392.2939\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[6392.2939453125, 6392.2939453125]"
            ]
          },
          "metadata": {},
          "execution_count": 72
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "H9doNDToqDru"
      },
      "source": [
        "Our model didn't perform very well, let's try a bigger model.\n",
        "\n",
        "We'll try 3 things:\n",
        "- Increasing the number of layers (2 -> 3).\n",
        "- Increasing the number of units in each layer (except for the output layer).\n",
        "- Changing the optimizer (from SGD to Adam).\n",
        "\n",
        "Everything else will stay the same."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "W59EqfqYimnR"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Add an extra layer and increase number of units\n",
        "insurance_model_2 = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(100), # 100 units\n",
        "  tf.keras.layers.Dense(10), # 10 units\n",
        "  tf.keras.layers.Dense(1) # 1 unit (important for output layer)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "insurance_model_2.compile(loss=tf.keras.losses.mae,\n",
        "                          optimizer=tf.keras.optimizers.Adam(), # Adam works but SGD doesn't \n",
        "                          metrics=['mae'])\n",
        "\n",
        "# Fit the model and save the history (we can plot this)\n",
        "history = insurance_model_2.fit(X_train, y_train, epochs=100, verbose=0)"
      ],
      "execution_count": 73,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "k9IbYWnOqmoT",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "8cb7a098-2cfa-45d3-e895-64cd357ce2fc"
      },
      "source": [
        "# Evaluate our larger model\n",
        "insurance_model_2.evaluate(X_test, y_test)"
      ],
      "execution_count": 74,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "9/9 [==============================] - 0s 2ms/step - loss: 4629.1626 - mae: 4629.1626\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[4629.16259765625, 4629.16259765625]"
            ]
          },
          "metadata": {},
          "execution_count": 74
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o9Rf3NosqriS"
      },
      "source": [
        "Much better! Using a larger model and the Adam optimizer results in almost half the error as the previous model.\n",
        "\n",
        "> 🔑 **Note:** For many problems, the [Adam optimizer](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam) is a great starting choice. See Andrei Karpathy's \"Adam is safe\" point from [*A Recipe for Training Neural Networks*](http://karpathy.github.io/2019/04/25/recipe/) for more. \n",
        "\n",
        "Let's check out the loss curves of our model, we should see a downward trend."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9SE55ANojcF_",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "outputId": "a8a18349-5f25-424f-e503-8f098b8a2517"
      },
      "source": [
        "# Plot history (also known as a loss curve)\n",
        "pd.DataFrame(history.history).plot()\n",
        "plt.ylabel(\"loss\")\n",
        "plt.xlabel(\"epochs\");"
      ],
      "execution_count": 75,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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nuum4uLiCAwMPOVbRCUlJSQmJpqUyr/MnTuX5cuXs3btWvr06eN9PjExkcbGRiorK1uN19yfu5ycHEpLS7nwwgsJCgoiKCiITz/9lMWLFxMUFERCQoLmuoMkJSUxbNiwVs8NHTqUgoICAO986r8p5+/BBx/kkUce4ZZbbmHEiBHcdtttzJ8/n4ULFwKa687UlrlNTEw85QtTzc3NlJeXn/f8qzR1UzabjbFjx7J69Wrvcx6Ph9WrV5OZmWliMt9nGAZz587l3XffZc2aNaSmprY6PnbsWKxWa6u5z83NpaCgQHN/jq666ip27NjB1q1bvY9x48YxY8YM77811x1jwoQJpyydsW/fPvr16wdAamoqiYmJreba5XKRlZWluT5HtbW1BAS0/vMZGBiIx+MBNNedqS1zm5mZSWVlJTk5Od4xa9aswePxkJGRcX4Bzus2culUb7zxhhEcHGy8+uqrxu7du43Zs2cbDofDKC4uNjuaT7v77ruNqKgo45NPPjGOHTvmfdTW1nrH/OQnPzH69u1rrFmzxti0aZORmZlpZGZmmpjaf3z923OGobnuKBs3bjSCgoKMX//610ZeXp7x+uuvG2FhYcZf/vIX75innnrKcDgcxnvvvWds377d+Pa3v22kpqYadXV1Jib3PTNnzjR69+5tLF++3MjPzzfeeecdIy4uznjooYe8YzTX7VdVVWVs2bLF2LJliwEYv/3tb40tW7YYhw8fNgyjbXN7zTXXGGPGjDGysrKMzz//3Bg0aJAxffr0886m0tTNPf/880bfvn0Nm81mXHzxxcaXX35pdiSfB5z28corr3jH1NXVGT/96U+N6OhoIywszPjOd75jHDt2zLzQfuQ/S5PmuuN88MEHxgUXXGAEBwcbQ4YMMV566aVWxz0ej/H4448bCQkJRnBwsHHVVVcZubm5JqX1XS6Xy7jvvvuMvn37GiEhIcaAAQOMxx57zGhoaPCO0Vy339q1a0/73+iZM2cahtG2uS0rKzOmT59uREREGHa73bjjjjuMqqqq885mMYyvLWEqIiIiIqele5pERERE2kClSURERKQNVJpERERE2kClSURERKQNVJpERERE2kClSURERKQNVJpERERE2kClSURERKQNVJpERDrIJ598gsViOWUDYhHxDypNIiIiIm2g0iQiIiLSBipNIuI3PB4PCxcuJDU1ldDQUEaNGsXbb78N/PvS2YoVKxg5ciQhISFccskl7Ny5s9Vr/OMf/2D48OEEBwfTv39/nn322VbHGxoaePjhh0lJSSE4OJi0tDT++Mc/thqTk5PDuHHjCAsLY/z48eTm5nqPbdu2jSuvvJLIyEjsdjtjx45l06ZNnTQjItKRVJpExG8sXLiQ1157jaVLl7Jr1y7mz5/PD37wAz799FPvmAcffJBnn32W7OxsevXqxY033khTUxPQUnZuvvlmbrnlFnbs2MGTTz7J448/zquvvur9/dtvv52//e1vLF68mD179vCHP/yBiIiIVjkee+wxnn32WTZt2kRQUBB33nmn99iMGTPo06cP2dnZ5OTk8Mgjj2C1Wjt3YkSkYxgiIn6gvr7eCAsLM7744otWz8+aNcuYPn26sXbtWgMw3njjDe+xsrIyIzQ01HjzzTcNwzCMW2+91bj66qtb/f6DDz5oDBs2zDAMw8jNzTUAY9WqVafNcPI9/vWvf3mfW7FihQEYdXV1hmEYRmRkpPHqq6+e/wcWkS6nM00i4hf2799PbW0tV199NREREd7Ha6+9xoEDB7zjMjMzvf+OiYkhPT2dPXv2ALBnzx4mTJjQ6nUnTJhAXl4ebrebrVu3EhgYyOWXX/6NWUaOHOn9d1JSEgClpaUALFiwgB/96EdMmjSJp556qlU2EeneVJpExC9UV1cDsGLFCrZu3ep97N6923tf0/kKDQ1t07ivX26zWCxAy/1WAE8++SS7du3i+uuvZ82aNQwbNox33323Q/KJSOdSaRIRvzBs2DCCg4MpKCggLS2t1SMlJcU77ssvv/T+u6Kign379jF06FAAhg4dyvr161u97vr16xk8eDCBgYGMGDECj8fT6h6p9hg8eDDz58/n448/5qabbuKVV145r9cTka4RZHYAEZGOEBkZyQMPPMD8+fPxeDxMnDgRp9PJ+vXrsdvt9OvXD4D//u//JjY2loSEBB577DHi4uKYOnUqAPfffz8XXXQRv/zlL/n+97/Phg0beOGFF/j9738PQP/+/Zk5cyZ33nknixcvZtSoURw+fJjS0lJuvvnms2asq6vjwQcf5Lvf/S6pqakcOXKE7Oxspk2b1mnzIiIdyOybqkREOorH4zF+97vfGenp6YbVajV69eplTJkyxfj000+9N2l/8MEHxvDhww2bzWZcfPHFxrZt21q9xttvv20MGzbMsFqtRt++fY1nnnmm1fG6ujpj/vz5RlJSkmGz2Yy0tDTjT3/6k2EY/74RvKKiwjt+y5YtBmDk5+cbDQ0Nxi233GKkpKQYNpvNSE5ONubOneu9SVxEujeLYRiGyb1NRKTTffLJJ1x55ZVUVFTgcDjMjiMiPkj3NImIiIi0gUqTiIiISBvo8pyIiIhIG+hMk4iIiEgbqDSJiIiItIFKk4iIiEgbqDSJiIiItIFKk4iIiEgbqDSJiIiItIFKk4iIiEgbqDSJiIiItMH/D++wNvMDNCMtAAAAAElFTkSuQmCC\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ckHqtn0srQ5q"
      },
      "source": [
        "From this, it looks like our model's loss (and MAE) were both still decreasing (in our case, MAE and loss are the same, hence the lines in the plot overlap eachother).\n",
        "\n",
        "What this tells us is the loss might go down if we try training it for longer.\n",
        "\n",
        "> 🤔 **Question:** How long should you train for? \n",
        "\n",
        "> It depends on what problem you're working on. Sometimes training won't take very long, other times it'll take longer than you expect. A common method is to set your model training for a very long time (e.g. 1000's of epochs) but set it up with an [EarlyStopping callback](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping) so it stops automatically when it stops improving. We'll see this in another module.\n",
        "\n",
        "Let's train the same model as above for a little longer. We can do this but calling fit on it again."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Ucs62jV8jl6N"
      },
      "source": [
        "# Try training for a little longer (100 more epochs)\n",
        "history_2 = insurance_model_2.fit(X_train, y_train, epochs=100, verbose=0)"
      ],
      "execution_count": 76,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "L2FZA1z1sxxs"
      },
      "source": [
        "How did the extra training go?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "cxtiYB3qs0PZ",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "35121d6a-4caf-4f81-80a8-9b300cc5b2c7"
      },
      "source": [
        "# Evaluate the model trained for 200 total epochs\n",
        "insurance_model_2_loss, insurance_model_2_mae = insurance_model_2.evaluate(X_test, y_test)\n",
        "insurance_model_2_loss, insurance_model_2_mae"
      ],
      "execution_count": 77,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "9/9 [==============================] - 0s 3ms/step - loss: 3483.4031 - mae: 3483.4031\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(3483.403076171875, 3483.403076171875)"
            ]
          },
          "metadata": {},
          "execution_count": 77
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MzUySYEOs-O_"
      },
      "source": [
        "Boom! Training for an extra 100 epochs we see about a 10% decrease in error.\n",
        "\n",
        "How does the visual look?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BtYKSLeQjuzL",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 449
        },
        "outputId": "34e3c9ca-0b68-43ca-a9ec-fa8464d8558d"
      },
      "source": [
        "# Plot the model trained for 200 total epochs loss curves\n",
        "pd.DataFrame(history_2.history).plot()\n",
        "plt.ylabel(\"loss\")\n",
        "plt.xlabel(\"epochs\"); # note: epochs will only show 100 since we overrid the history variable"
      ],
      "execution_count": 78,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ],
            "image/png": "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c6kQdVIxfYdTa1ixcYxDOTvNjiMiImIqFaJOytPLm1z3WAAKdujCahER6dxUiDqxowENF1ZX5zZtWhYREZGOSoWoE3NEDADA5+gWk5OIiIiYS4WoEwvs2XBhdffKbF1YLSIinZoKUScWN/Bcag13QinhwB6dJRIRkc5LhagT8/b1Z5dXPwAOff9vk9OIiIiYR4WokysLb5jo1W3/NyYnERERMY8KUSfnn3AhANFlG3UdkYiIdFoqRJ1cr2EXU2tYieAoefuyzY4jIiJiChWiTs7HL4DdngkA5GXqOiIREemcVIiEkvARDT/s/9bcICIiIiZRIZL/XUdUusHkJCIiIuZQIRJ6DbuYOsNKJIfJ27fd7DgiIiKtToVI8PUPZLdHHwAObPzS5DQiIiKtT4VIACgOPwsAi64jEhGRTkiFSADw6zMKgG66jkhERDohFSIBoOewi6k33IgyCsjP2Wl2HBERkValQiQA+Nu6sMcjHoDcjakmpxEREWldKkTidDSsYV4zY+9/TE4iIiLSulSIxMm3d8PziKJ0HZGIiHQyKkTi1HP4GOyGhe5GPgUHdpsdR0REpNWoEIlTQGDw/64j2qDnEYmISOehQiSNHA3973VEe1aZnERERKT1qBBJI36J4wCILVmL4XCYnEZERKR1tJlCNG/ePCwWC9OnT3cuq66uZurUqYSEhODv78/kyZMpKCho9L6cnBwmTZqEr68v4eHhzJw5k/r6+kZjVq5cybBhw/Dy8iI+Pp7Fixe3wh61T73PGkO14UE4ReRs32h2HBERkVbRJgpReno6L730EoMGDWq0fMaMGXz66ae8//77rFq1iry8PK644grnervdzqRJk6itreW7777jjTfeYPHixcyZM8c5Zu/evUyaNImLLrqIzMxMpk+fzs0338wXX3zRavvXnnj7+LHDp+F/h0Mb/2VyGhERkdZheiGqqKggJSWFV155hS5dujiXl5aW8ve//52nn36aiy++mOHDh/P666/z3XffsWbNGgC+/PJLtm7dyltvvcWQIUOYMGECjzzyCC+++CK1tbUALFq0iLi4OObPn0+/fv2YNm0av/71r3nmmWdM2d/2oLL7+QD45K42OYmIiEjrML0QTZ06lUmTJjFmzJhGyzMyMqirq2u0vG/fvsTExJCWlgZAWloaAwcOJCIiwjlm3LhxlJWVsWXLFueY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GTOGtLQ0E5N1PKWlpQAEBwcDkJGRQV1dXaNj37dvX2JiYnTsm2nq1KlMmjSp0TEFHWtX+uSTT0hKSuLKK68kPDycoUOH8sorrzjX7927l/z8/EbHOjAwkBEjRuhYN8PIkSP56quv2LFjBwDff/8933zzDRMmTAB0vFtKU45rWloaQUFBJCUlOceMGTMGNzc31q5de0afb/rkrp3RkSNHsNvtRERENFoeERHBtm3bTErV8TgcDqZPn865557LgAEDAMjPz8fT0/OEyXojIiLIz883IWX7tnTpUjZs2EB6evoJ63SsXWfPnj0sXLiQu+++mz/96U+kp6dz55134unpyQ033OA8nif7b4qO9embPXs2ZWVl9O3bF6vVit1u59FHHyUlJQVAx7uFNOW45ufnEx4e3mi9u7s7wcHBZ3zsVYikw5o6dSqbN2/mm2++MTtKh5Sbm8tdd91Famoq3t7eZsfp0BwOB0lJSTz22GMADB06lM2bN7No0SJuuOEGk9N1PO+99x5Llizh7bffpn///mRmZjJ9+nSioqJ0vDswfWVmgtDQUKxW6wl32xQUFBAZGWlSqo5l2rRpLFu2jK+//pru3bs7l0dGRlJbW0tJSUmj8Tr2py8jI4PCwkKGDRuGu7s77u7urFq1igULFuDu7k5ERISOtYt07dqVxMTERsv69etHTk4OgPN46r8prjFz5kxmz57N1VdfzcCBA7nuuuuYMWMGc+fOBXS8W0pTjmtkZOQJNx/V19dTVFR0xsdehcgEnp6eDB8+nK+++sq5zOFw8NVXX5GcnGxisvbPMAymTZvGRx99xIoVK4iLi2u0fvjw4Xh4eDQ69tu3bycnJ0fH/jSNHj2arKwsMjMzna+kpCRSUlKcP+tYu8a55557wuMjduzYQWxsLABxcXFERkY2OtZlZWWsXbtWx7oZKisrcXNr/OfRarXicDgAHe+W0pTjmpycTElJCRkZGc4xK1aswOFwMGLEiDMLcEaXZEuzLV261PDy8jIWL15sbN261bj11luNoKAgIz8/3+xo7dodd9xhBAYGGitXrjQOHTrkfFVWVjrH3H777UZMTIyxYsUKY/369UZycrKRnJxsYuqO44d3mRmGjrWrrFu3znB3dzceffRRY+fOncaSJUsMX19f46233nKOmTdvnhEUFGT885//NDZt2mRcfvnlRlxcnFFVVWVi8vbphhtuMLp162YsW7bM2Lt3r/GPf/zDCA0NNe69917nGB3v5ikvLzc2btxobNy40QCMp59+2ti4caOxf/9+wzCadlzHjx9vDB061Fi7dq3xzTffGL179zZ++9vfnnE2FSITPf/880ZMTIzh6elpnH322caaNWvMjtTuASd9vf76684xVVVVxu9//3ujS5cuhq+vr/GrX/3KOHTokHmhO5AfFyIda9f59NNPjQEDBhheXl5G3759jZdffrnReofDYTzwwANGRESE4eXlZYwePdrYvn27SWnbt7KyMuOuu+4yYmJiDG9vb6Nnz57G/fffb9TU1DjH6Hg3z9dff33S/0bfcMMNhmE07bgePXrU+O1vf2v4+/sbNpvNuPHGG43y8vIzzmYxjB88elNERESkE9I1RCIiItLpqRCJiIhIp6dCJCIiIp2eCpGIiIh0eipEIiIi0umpEImIiEinp0IkIiIinZ4KkYiIiHR6KkQiIk2wcuVKLBbLCZPVikjHoEIkIiIinZ4KkYiIiHR6KkQi0i44HA7mzp1LXFwcPj4+DB48mA8++AD439dZy5cvZ9CgQXh7e3POOeewefPmRtv48MMP6d+/P15eXvTo0YP58+c3Wl9TU8OsWbOIjo7Gy8uL+Ph4/v73vzcak5GRQVJSEr6+vowcOZLt27c7133//fdcdNFFBAQEYLPZGD58OOvXr2+hIyIirqRCJCLtwty5c3nzzTdZtGgRW7ZsYcaMGVx77bWsWrXKOWbmzJnMnz+f9PR0wsLC+MUvfkFdXR3QUGSuuuoqrr76arKysnjooYd44IEHWLx4sfP9119/Pe+88w4LFiwgOzubl156CX9//0Y57r//fubPn8/69etxd3fnpptucq5LSUmhe/fupKenk5GRwezZs/Hw8GjZAyMirmGIiLRx1dXVhq+vr/Hdd981Wj5lyhTjt7/9rfH1118bgLF06VLnuqNHjxo+Pj7Gu+++axiGYVxzzTXGJZdc0uj9M2fONBITEw3DMIzt27cbgJGamnrSDMc/49///rdz2fLlyw3AqKqqMgzDMAICAozFixef+Q6LSKvTGSIRafN27dpFZWUll1xyCf7+/s7Xm2++ye7du53jkpOTnT8HBweTkJBAdnY2ANnZ2Zx77rmNtnvuueeyc+dO7HY7mZmZWK1WLrzwwlNmGTRokPPnrl27AlBYWAjA3Xffzc0338yYMWOYN29eo2wi0rapEIlIm1dRUQHA8uXLyczMdL62bt3qvI7oTPn4+DRp3A+/ArNYLEDD9U0ADz30EFu2bGHSpEmsWLGCxMREPvroI5fkE5GWpUIkIm1eYmIiXl5e5OTkEB8f3+gVHR3tHLdmzRrnz8XFxezYsYN+/foB0K9fP7799ttG2/3222/p06cPVquVgQMH4nA4Gl2T1Bx9+vRhxowZfPnll1xxxRW8/vrrZ7Q9EWkd7mYHEBH5OQEBAdxzzz3MmDEDh8PBeeedR2lpKd9++y02m43Y2FgAHn74YUJCQoiIiOD+++8nNDSUX/7ylwD88Y9/5KyzzuKRRx7hN7/5DWlpabzwwgv87W9/A6BHjx7ccMMN3HTTTSxYsIDBgwezf/9+CgsLueqqq342Y1VVFTNnzuTXv/41cXFxHDhwgPT0dCZPntxix0VEXMjsi5hERJrC4XAYzz77rJGQkGB4eHgYYWFhxrhx44xVq1Y5L3j+9NNPjf79+xuenp7G2WefbXz//feNtvHBBx8YiYmJhoeHhxETE2M8+eSTjdZXVVUZM2bMMLp27Wp4enoa8fHxxmuvvWYYxv8uqi4uLnaO37hxowEYe/fuNWpqaoyrr77aiI6ONjw9PY2oqChj2rRpzguuRaRtsxiGYZjcyUREzsjKlSu56KKLKC4uJigoyOw4ItIO6RoiERER6fRUiERERKTT01dmIiIi0unpDJGIiIh0eipEIiIi0umpEImIiEinp0IkIiIinZ4KkYiIiHR6KkQiIiLS6akQiYiISKenQiQiIiKd3v8DC5IkDjY41PUAAAAASUVORK5CYII=\n"
          },
          "metadata": {}
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HS8xYkvIuVZZ"
      },
      "source": [
        "## Preprocessing data (normalization and standardization)\n",
        "\n",
        "A common practice when working with neural networks is to make sure all of the data you pass to them is in the range 0 to 1.\n",
        "\n",
        "This practice is called **normalization** (scaling all values from their original range to, e.g. between 0 and 100,000 to be between 0 and 1).\n",
        "\n",
        "There is another process call **standardization** which converts all of your data to unit variance and 0 mean.\n",
        "\n",
        "These two practices are often part of a preprocessing pipeline (a series of functions to prepare your data for use with neural networks).\n",
        "\n",
        "Knowing this, some of the major steps you'll take to preprocess your data for a neural network include:\n",
        "* Turning all of your data to numbers (a neural network can't handle strings).\n",
        "* Making sure your data is in the right shape (verifying input and output shapes).\n",
        "* [**Feature scaling**](https://scikit-learn.org/stable/modules/preprocessing.html#preprocessing-scaler):\n",
        "    * Normalizing data (making sure all values are between 0 and 1). This is done by subtracting the minimum value then dividing by the maximum value minus the minimum. This is also referred to as min-max scaling.\n",
        "    * Standardization (making sure all values have a mean of 0 and a variance of 1). This is done by subtracting the mean value from the target feature and then dividing it by the standard deviation.\n",
        "    * Which one should you use?\n",
        "      * **With neural networks you'll tend to favour normalization** as they tend to prefer values between 0 and 1 (you'll see this espcially with image processing), however, you'll often find a neural network can perform pretty well with minimal feature scaling.\n",
        "\n",
        "> 📖 **Resource:** For more on preprocessing data, I'd recommend reading the following resources:\n",
        "* [Scikit-Learn's documentation on preprocessing data](https://scikit-learn.org/stable/modules/preprocessing.html#preprocessing-data).\n",
        "* [Scale, Standardize or Normalize with Scikit-Learn by Jeff Hale](https://towardsdatascience.com/scale-standardize-or-normalize-with-scikit-learn-6ccc7d176a02).\n",
        "\n",
        "We've already turned our data into numbers using `get_dummies()`, let's see how we'd normalize it as well."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9v7P20A2d7H6"
      },
      "source": [
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "import tensorflow as tf\n",
        "\n",
        "# Read in the insurance dataset\n",
        "insurance = pd.read_csv(\"https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/insurance.csv\")"
      ],
      "execution_count": 79,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "vir8UAIwlUOo",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "outputId": "e8481873-da05-4f85-a4b9-ec1595ada02a"
      },
      "source": [
        "# Check out the data\n",
        "insurance.head()"
      ],
      "execution_count": 80,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   age     sex     bmi  children smoker     region      charges\n",
              "0   19  female  27.900         0    yes  southwest  16884.92400\n",
              "1   18    male  33.770         1     no  southeast   1725.55230\n",
              "2   28    male  33.000         3     no  southeast   4449.46200\n",
              "3   33    male  22.705         0     no  northwest  21984.47061\n",
              "4   32    male  28.880         0     no  northwest   3866.85520"
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-761883eb-d95f-49e2-983b-3353d19b1b53\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>age</th>\n",
              "      <th>sex</th>\n",
              "      <th>bmi</th>\n",
              "      <th>children</th>\n",
              "      <th>smoker</th>\n",
              "      <th>region</th>\n",
              "      <th>charges</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>19</td>\n",
              "      <td>female</td>\n",
              "      <td>27.900</td>\n",
              "      <td>0</td>\n",
              "      <td>yes</td>\n",
              "      <td>southwest</td>\n",
              "      <td>16884.92400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>18</td>\n",
              "      <td>male</td>\n",
              "      <td>33.770</td>\n",
              "      <td>1</td>\n",
              "      <td>no</td>\n",
              "      <td>southeast</td>\n",
              "      <td>1725.55230</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>28</td>\n",
              "      <td>male</td>\n",
              "      <td>33.000</td>\n",
              "      <td>3</td>\n",
              "      <td>no</td>\n",
              "      <td>southeast</td>\n",
              "      <td>4449.46200</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>33</td>\n",
              "      <td>male</td>\n",
              "      <td>22.705</td>\n",
              "      <td>0</td>\n",
              "      <td>no</td>\n",
              "      <td>northwest</td>\n",
              "      <td>21984.47061</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>32</td>\n",
              "      <td>male</td>\n",
              "      <td>28.880</td>\n",
              "      <td>0</td>\n",
              "      <td>no</td>\n",
              "      <td>northwest</td>\n",
              "      <td>3866.85520</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-761883eb-d95f-49e2-983b-3353d19b1b53')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-761883eb-d95f-49e2-983b-3353d19b1b53 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-761883eb-d95f-49e2-983b-3353d19b1b53');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ]
          },
          "metadata": {},
          "execution_count": 80
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SHMQiNosg3J3"
      },
      "source": [
        "Now, just as before, we need to transform the non-numerical columns into numbers and this time we'll also be normalizing the numerical columns with different ranges (to make sure they're all between 0 and 1).\n",
        "\n",
        "To do this, we're going to use a few classes from Scikit-Learn:\n",
        "* [`make_column_transformer`](https://scikit-learn.org/stable/modules/generated/sklearn.compose.make_column_transformer.html) - build a multi-step data preprocessing function for the folllowing transformations:\n",
        "  * [`MinMaxScaler`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html) - make sure all numerical columns are normalized (between 0 and 1).\n",
        "  * [`OneHotEncoder`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html) - one hot encode the non-numerical columns.\n",
        "\n",
        "Let's see them in action."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "-x9JwbV0hqWh"
      },
      "source": [
        "from sklearn.compose import make_column_transformer\n",
        "from sklearn.preprocessing import MinMaxScaler, OneHotEncoder\n",
        "\n",
        "# Create column transformer (this will help us normalize/preprocess our data)\n",
        "ct = make_column_transformer(\n",
        "    (MinMaxScaler(), [\"age\", \"bmi\", \"children\"]), # get all values between 0 and 1\n",
        "    (OneHotEncoder(handle_unknown=\"ignore\"), [\"sex\", \"smoker\", \"region\"])\n",
        ")\n",
        "\n",
        "# Create X & y\n",
        "X = insurance.drop(\"charges\", axis=1)\n",
        "y = insurance[\"charges\"]\n",
        "\n",
        "# Build our train and test sets (use random state to ensure same split as before)\n",
        "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
        "\n",
        "# Fit column transformer on the training data only (doing so on test data would result in data leakage)\n",
        "ct.fit(X_train)\n",
        "\n",
        "# Transform training and test data with normalization (MinMaxScalar) and one hot encoding (OneHotEncoder)\n",
        "X_train_normal = ct.transform(X_train)\n",
        "X_test_normal = ct.transform(X_test)"
      ],
      "execution_count": 81,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tz58y3nPiBJ-"
      },
      "source": [
        "Now we've normalized it and one-hot encoding it, what does our data look like now?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VODt2YiziK45",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "58851acc-9ea2-4795-f0b5-f43c609b7bdb"
      },
      "source": [
        "# Non-normalized and non-one-hot encoded data example\n",
        "X_train.loc[0]"
      ],
      "execution_count": 82,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "age                19\n",
              "sex            female\n",
              "bmi              27.9\n",
              "children            0\n",
              "smoker            yes\n",
              "region      southwest\n",
              "Name: 0, dtype: object"
            ]
          },
          "metadata": {},
          "execution_count": 82
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mMYDXdwUnNVt",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "a053ca20-a44f-423e-9795-1d0c66b30633"
      },
      "source": [
        "# Normalized and one-hot encoded example\n",
        "X_train_normal[0]"
      ],
      "execution_count": 83,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([0.60869565, 0.10734463, 0.4       , 1.        , 0.        ,\n",
              "       1.        , 0.        , 0.        , 1.        , 0.        ,\n",
              "       0.        ])"
            ]
          },
          "metadata": {},
          "execution_count": 83
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9iI4KtfWib44"
      },
      "source": [
        "How about the shapes?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SFmxzqrWntj7",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "0cf4d413-e6eb-4da2-a449-08ef3aefc02f"
      },
      "source": [
        "# Notice the normalized/one-hot encoded shape is larger because of the extra columns\n",
        "X_train_normal.shape, X_train.shape"
      ],
      "execution_count": 84,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "((1070, 11), (1070, 6))"
            ]
          },
          "metadata": {},
          "execution_count": 84
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MST951aYijTS"
      },
      "source": [
        "Our data is normalized and numerical, let's model it.\n",
        "\n",
        "We'll use the same model as `insurance_model_2`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TdHnIQqll83Y",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "11ea61c0-8ab5-4ca7-ec68-bde1e94e195d"
      },
      "source": [
        "# Set random seed\n",
        "tf.random.set_seed(42)\n",
        "\n",
        "# Build the model (3 layers, 100, 10, 1 units)\n",
        "insurance_model_3 = tf.keras.Sequential([\n",
        "  tf.keras.layers.Dense(100),\n",
        "  tf.keras.layers.Dense(10),\n",
        "  tf.keras.layers.Dense(1)\n",
        "])\n",
        "\n",
        "# Compile the model\n",
        "insurance_model_3.compile(loss=tf.keras.losses.mae,\n",
        "                          optimizer=tf.keras.optimizers.Adam(),\n",
        "                          metrics=['mae'])\n",
        "\n",
        "# Fit the model for 200 epochs (same as insurance_model_2)\n",
        "insurance_model_3.fit(X_train_normal, y_train, epochs=200, verbose=0) "
      ],
      "execution_count": 85,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "<keras.callbacks.History at 0x7f004cd64af0>"
            ]
          },
          "metadata": {},
          "execution_count": 85
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-DjwktO6jW41"
      },
      "source": [
        "Let's evaluate the model on normalized test set."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "sBcXZu9AnZfP",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "383dfb1a-ef18-4ad7-c696-41453afb729f"
      },
      "source": [
        "# Evaulate 3rd model\n",
        "insurance_model_3_loss, insurance_model_3_mae = insurance_model_3.evaluate(X_test_normal, y_test)"
      ],
      "execution_count": 86,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "9/9 [==============================] - 0s 3ms/step - loss: 3171.2595 - mae: 3171.2595\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZlHro290jhtX"
      },
      "source": [
        "And finally, let's compare the results from `insurance_model_2` (trained on non-normalized data) and `insurance_model_3` (trained on normalized data)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ybZtnVlNjCJO",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "d4713c7f-d84e-4a9f-f1b8-a97f9a457e16"
      },
      "source": [
        "# Compare modelling results from non-normalized data and normalized data\n",
        "insurance_model_2_mae, insurance_model_3_mae"
      ],
      "execution_count": 87,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(3483.403076171875, 3171.259521484375)"
            ]
          },
          "metadata": {},
          "execution_count": 87
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gUttViY4jzi8"
      },
      "source": [
        "From this we can see normalizing the data results in 10% less error using the same model than not normalizing the data.\n",
        "\n",
        "This is **one of the main benefits of normalization: faster convergence time** (a fancy way of saying, your model gets to better results faster).\n",
        "\n",
        "`insurance_model_2` may have eventually achieved the same results as `insurance_model_3` if we left it training for longer. \n",
        "\n",
        "Also, the results may change if we were to alter the architectures of the models, e.g. more hidden units per layer or more layers.\n",
        "\n",
        "But since our main goal as neural network practitioners is to decrease the time between experiments, anything that helps us get better results sooner is a plus."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NhIPO_KqocHP"
      },
      "source": [
        "## 🛠 Exercises\n",
        "\n",
        "We've a covered a whole lot pretty quickly.\n",
        "\n",
        "So now it's time to have a **play around** with a few things and start to build up your intuition.\n",
        "\n",
        "I emphasise the words play around because that's very important. Try a few things out, run the code and see what happens.\n",
        "\n",
        "1. Create your own regression dataset (or make the one we created in \"Create data to view and fit\" bigger) and build fit a model to it.\n",
        "2. Try building a neural network with 4 Dense layers and fitting it to your own regression dataset, how does it perform?\n",
        "3. Try and improve the results we got on the insurance dataset, some things you might want to try include:\n",
        "  * Building a larger model (how does one with 4 dense layers go?).\n",
        "  * Increasing the number of units in each layer.\n",
        "  * Lookup the documentation of [Adam](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam) and find out what the first parameter is, what happens if you increase it by 10x?\n",
        "  * What happens if you train for longer (say 300 epochs instead of 200)? \n",
        "4. Import the [Boston pricing dataset](https://www.tensorflow.org/api_docs/python/tf/keras/datasets/boston_housing/load_data) from TensorFlow [`tf.keras.datasets`](https://www.tensorflow.org/api_docs/python/tf/keras/datasets) and model it.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AyiHG2nubmu7"
      },
      "source": [
        "## 📖 Extra curriculum\n",
        "\n",
        "If you're looking for extra materials relating to this notebook, I'd check out the following:\n",
        "\n",
        "* [MIT introduction deep learning lecture 1](https://youtu.be/njKP3FqW3Sk) - gives a great overview of what's happening behind all of the code we're running.\n",
        "* Reading: 1-hour of [Chapter 1 of Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/chap1.html) by Michael Nielson - a great in-depth and hands-on example of the intuition behind neural networks.\n",
        "\n",
        "To practice your regression modelling with TensorFlow, I'd also encourage you to look through [Lion Bridge's collection of datasets](https://lionbridge.ai/datasets/) or [Kaggle's datasets](https://www.kaggle.com/data), find a regression dataset which sparks your interest and try to model."
      ]
    }
  ]
}